1use crate::values::Value;
18use alloc::vec;
19use core::cmp::Ordering;
20use core::iter::Peekable;
21
22#[macro_export]
54macro_rules! destructure_cbor_map {
55 ( let { $( $key:expr => $variable:ident, )+ } = $map:expr; ) => {
56 #[cfg(test)]
60 $crate::assert_sorted_keys!($( $key, )+);
61
62 use $crate::values::{IntoCborValue, Value};
63 use $crate::macros::destructure_cbor_map_peek_value;
64
65 let mut it = $map.into_iter().peekable();
74 $(
75 let $variable: Option<Value> = destructure_cbor_map_peek_value(&mut it, $key.into_cbor_value());
76 )+
77 };
78}
79
80pub fn destructure_cbor_map_peek_value(
92 it: &mut Peekable<vec::IntoIter<(Value, Value)>>,
93 needle: Value,
94) -> Option<Value> {
95 loop {
96 match it.peek() {
97 None => return None,
98 Some(item) => {
99 let key: &Value = &item.0;
100 match key.cmp(&needle) {
101 Ordering::Less => {
102 it.next();
103 }
104 Ordering::Equal => {
105 let value: Value = it.next().unwrap().1;
106 return Some(value);
107 }
108 Ordering::Greater => return None,
109 }
110 }
111 }
112 }
113}
114
115#[macro_export]
117macro_rules! assert_sorted_keys {
118 ( $key:expr, ) => {
120 };
121
122 ( $key1:expr, $key2:expr, $( $keys:expr, )* ) => {
123 {
124 use $crate::values::{IntoCborValue, Value};
125 let k1: Value = $key1.into_cbor_value();
126 let k2: Value = $key2.into_cbor_value();
127 assert!(
128 k1 < k2,
129 "{:?} < {:?} failed. The destructure_cbor_map! macro requires keys in sorted order.",
130 k1,
131 k2,
132 );
133 }
134 $crate::assert_sorted_keys!($key2, $( $keys, )*);
135 };
136}
137
138#[macro_export]
156macro_rules! cbor_map {
157 ( $( $key:expr => $value:expr, )+ ) => {
159 cbor_map! ( $($key => $value),+ )
160 };
161
162 ( $( $key:expr => $value:expr ),* ) => {
163 {
164 #[allow(unused_imports)]
166 use $crate::values::IntoCborValue;
167 let mut _map = ::alloc::vec::Vec::new();
168 $(
169 _map.push(($key.into_cbor_value(), $value.into_cbor_value()));
170 )*
171 $crate::values::Value::Map(_map)
172 }
173 };
174}
175
176#[macro_export]
197macro_rules! cbor_map_options {
198 ( $( $key:expr => $value:expr, )+ ) => {
200 cbor_map_options! ( $($key => $value),+ )
201 };
202
203 ( $( $key:expr => $value:expr ),* ) => {
204 {
205 #[allow(unused_imports)]
207 use $crate::values::{IntoCborValue, IntoCborValueOption};
208 let mut _map = ::alloc::vec::Vec::<(_, $crate::values::Value)>::new();
209 $(
210 {
211 let opt: Option<$crate::values::Value> = $value.into_cbor_value_option();
212 if let Some(val) = opt {
213 _map.push(($key.into_cbor_value(), val));
214 }
215 }
216 )*
217 $crate::values::Value::Map(_map)
218 }
219 };
220}
221
222#[macro_export]
224macro_rules! cbor_map_collection {
225 ( $tree:expr ) => {{
226 $crate::values::Value::from($tree)
227 }};
228}
229
230#[macro_export]
242macro_rules! cbor_array {
243 ( $( $value:expr, )+ ) => {
245 cbor_array! ( $($value),+ )
246 };
247
248 ( $( $value:expr ),* ) => {
249 {
250 #[allow(unused_imports)]
252 use $crate::values::IntoCborValue;
253 $crate::values::Value::Array(vec![ $( $value.into_cbor_value(), )* ])
254 }
255 };
256}
257
258#[macro_export]
260macro_rules! cbor_array_vec {
261 ( $vec:expr ) => {{
262 use $crate::values::IntoCborValue;
263 $crate::values::Value::Array($vec.into_iter().map(|x| x.into_cbor_value()).collect())
264 }};
265}
266
267#[macro_export]
269macro_rules! cbor_true {
270 ( ) => {
271 $crate::values::Value::Simple($crate::values::SimpleValue::TrueValue)
272 };
273}
274
275#[macro_export]
277macro_rules! cbor_false {
278 ( ) => {
279 $crate::values::Value::Simple($crate::values::SimpleValue::FalseValue)
280 };
281}
282
283#[macro_export]
285macro_rules! cbor_null {
286 ( ) => {
287 $crate::values::Value::Simple($crate::values::SimpleValue::NullValue)
288 };
289}
290
291#[macro_export]
293macro_rules! cbor_undefined {
294 ( ) => {
295 $crate::values::Value::Simple($crate::values::SimpleValue::Undefined)
296 };
297}
298
299#[macro_export]
301macro_rules! cbor_bool {
302 ( $x:expr ) => {
303 $crate::values::Value::bool_value($x)
304 };
305}
306
307#[macro_export]
309macro_rules! cbor_unsigned {
310 ( $x:expr ) => {
311 $crate::values::Value::Unsigned($x)
312 };
313}
314
315#[macro_export]
317macro_rules! cbor_int {
318 ( $x:expr ) => {
319 $crate::values::Value::integer($x)
320 };
321}
322
323#[macro_export]
325macro_rules! cbor_text {
326 ( $x:expr ) => {
327 $crate::values::Value::TextString($x.into())
328 };
329}
330
331#[macro_export]
333macro_rules! cbor_bytes {
334 ( $x:expr ) => {
335 $crate::values::Value::ByteString($x)
336 };
337}
338
339#[macro_export]
341macro_rules! cbor_tagged {
342 ( $t:expr, $x: expr ) => {
343 $crate::values::Value::Tag($t, ::alloc::boxed::Box::new($x))
344 };
345}
346
347#[macro_export]
357macro_rules! cbor_bytes_lit {
358 ( $x:expr ) => {
359 $crate::cbor_bytes!(($x as &[u8]).to_vec())
360 };
361}
362
363#[cfg(test)]
364mod test {
365 use super::super::values::{SimpleValue, Value};
366 use alloc::{string::String, vec, vec::Vec};
367
368 #[test]
369 fn test_cbor_simple_values() {
370 assert_eq!(cbor_true!(), Value::Simple(SimpleValue::TrueValue));
371 assert_eq!(cbor_false!(), Value::Simple(SimpleValue::FalseValue));
372 assert_eq!(cbor_null!(), Value::Simple(SimpleValue::NullValue));
373 assert_eq!(cbor_undefined!(), Value::Simple(SimpleValue::Undefined));
374 }
375
376 #[test]
377 fn test_cbor_bool() {
378 assert_eq!(cbor_bool!(true), Value::Simple(SimpleValue::TrueValue));
379 assert_eq!(cbor_bool!(false), Value::Simple(SimpleValue::FalseValue));
380 }
381
382 #[test]
383 fn test_cbor_int_unsigned() {
384 assert_eq!(cbor_int!(0), Value::Unsigned(0));
385 assert_eq!(cbor_int!(1), Value::Unsigned(1));
386 assert_eq!(cbor_int!(123456), Value::Unsigned(123456));
387 assert_eq!(
388 cbor_int!(core::i64::MAX),
389 Value::Unsigned(core::i64::MAX as u64)
390 );
391 }
392
393 #[test]
394 fn test_cbor_int_negative() {
395 assert_eq!(cbor_int!(-1), Value::Negative(-1));
396 assert_eq!(cbor_int!(-123456), Value::Negative(-123456));
397 assert_eq!(cbor_int!(core::i64::MIN), Value::Negative(core::i64::MIN));
398 }
399
400 #[test]
401 fn test_cbor_int_literals() {
402 let a = cbor_array![
403 core::i64::MIN,
404 core::i32::MIN,
405 -123456,
406 -1,
407 0,
408 1,
409 123456,
410 core::i32::MAX,
411 core::i64::MAX,
412 core::u64::MAX,
413 ];
414 let b = Value::Array(vec![
415 Value::Negative(core::i64::MIN),
416 Value::Negative(core::i32::MIN as i64),
417 Value::Negative(-123456),
418 Value::Negative(-1),
419 Value::Unsigned(0),
420 Value::Unsigned(1),
421 Value::Unsigned(123456),
422 Value::Unsigned(core::i32::MAX as u64),
423 Value::Unsigned(core::i64::MAX as u64),
424 Value::Unsigned(core::u64::MAX),
425 ]);
426 assert_eq!(a, b);
427 }
428
429 #[test]
430 fn test_cbor_array() {
431 let a = cbor_array![
432 -123,
433 456,
434 true,
435 cbor_null!(),
436 "foo",
437 b"bar",
438 cbor_array![],
439 cbor_array![0, 1],
440 cbor_map! {},
441 cbor_map! {2 => 3},
442 ];
443 let b = Value::Array(vec![
444 Value::Negative(-123),
445 Value::Unsigned(456),
446 Value::Simple(SimpleValue::TrueValue),
447 Value::Simple(SimpleValue::NullValue),
448 Value::TextString(String::from("foo")),
449 Value::ByteString(b"bar".to_vec()),
450 Value::Array(Vec::new()),
451 Value::Array(vec![Value::Unsigned(0), Value::Unsigned(1)]),
452 Value::Map(Vec::new()),
453 Value::Map(
454 [(Value::Unsigned(2), Value::Unsigned(3))]
455 .iter()
456 .cloned()
457 .collect(),
458 ),
459 ]);
460 assert_eq!(a, b);
461 }
462
463 #[test]
464 fn test_cbor_array_vec_empty() {
465 let a = cbor_array_vec!(Vec::<bool>::new());
466 let b = Value::Array(Vec::new());
467 assert_eq!(a, b);
468 }
469
470 #[test]
471 fn test_cbor_array_vec_int() {
472 let a = cbor_array_vec!(vec![1, 2, 3, 4]);
473 let b = Value::Array(vec![
474 Value::Unsigned(1),
475 Value::Unsigned(2),
476 Value::Unsigned(3),
477 Value::Unsigned(4),
478 ]);
479 assert_eq!(a, b);
480 }
481
482 #[test]
483 fn test_cbor_array_vec_text() {
484 let a = cbor_array_vec!(vec!["a", "b", "c"]);
485 let b = Value::Array(vec![
486 Value::TextString(String::from("a")),
487 Value::TextString(String::from("b")),
488 Value::TextString(String::from("c")),
489 ]);
490 assert_eq!(a, b);
491 }
492
493 #[test]
494 fn test_cbor_array_vec_bytes() {
495 let a = cbor_array_vec!(vec![b"a", b"b", b"c"]);
496 let b = Value::Array(vec![
497 Value::ByteString(b"a".to_vec()),
498 Value::ByteString(b"b".to_vec()),
499 Value::ByteString(b"c".to_vec()),
500 ]);
501 assert_eq!(a, b);
502 }
503
504 #[test]
505 fn test_cbor_map() {
506 let a = cbor_map! {
507 -1 => -23,
508 4 => 56,
509 "foo" => true,
510 b"bar" => cbor_null!(),
511 5 => "foo",
512 6 => b"bar",
513 7 => cbor_array![],
514 8 => cbor_array![0, 1],
515 9 => cbor_map!{},
516 10 => cbor_map!{2 => 3},
517 };
518 let b = Value::Map(
519 [
520 (Value::Negative(-1), Value::Negative(-23)),
521 (Value::Unsigned(4), Value::Unsigned(56)),
522 (
523 Value::TextString(String::from("foo")),
524 Value::Simple(SimpleValue::TrueValue),
525 ),
526 (
527 Value::ByteString(b"bar".to_vec()),
528 Value::Simple(SimpleValue::NullValue),
529 ),
530 (Value::Unsigned(5), Value::TextString(String::from("foo"))),
531 (Value::Unsigned(6), Value::ByteString(b"bar".to_vec())),
532 (Value::Unsigned(7), Value::Array(Vec::new())),
533 (
534 Value::Unsigned(8),
535 Value::Array(vec![Value::Unsigned(0), Value::Unsigned(1)]),
536 ),
537 (Value::Unsigned(9), Value::Map(Vec::new())),
538 (
539 Value::Unsigned(10),
540 Value::Map(
541 [(Value::Unsigned(2), Value::Unsigned(3))]
542 .iter()
543 .cloned()
544 .collect(),
545 ),
546 ),
547 ]
548 .iter()
549 .cloned()
550 .collect(),
551 );
552 assert_eq!(a, b);
553 }
554
555 #[test]
556 fn test_cbor_map_options() {
557 let a = cbor_map_options! {
558 -1 => -23,
559 4 => Some(56),
560 11 => None::<String>,
561 "foo" => true,
562 12 => None::<&str>,
563 b"bar" => Some(cbor_null!()),
564 13 => None::<Vec<u8>>,
565 5 => "foo",
566 14 => None::<&[u8]>,
567 6 => Some(b"bar" as &[u8]),
568 15 => None::<bool>,
569 7 => cbor_array![],
570 16 => None::<i32>,
571 8 => Some(cbor_array![0, 1]),
572 17 => None::<i64>,
573 9 => cbor_map!{},
574 18 => None::<u64>,
575 10 => Some(cbor_map!{2 => 3}),
576 };
577 let b = Value::Map(
578 [
579 (Value::Negative(-1), Value::Negative(-23)),
580 (Value::Unsigned(4), Value::Unsigned(56)),
581 (
582 Value::TextString(String::from("foo")),
583 Value::Simple(SimpleValue::TrueValue),
584 ),
585 (
586 Value::ByteString(b"bar".to_vec()),
587 Value::Simple(SimpleValue::NullValue),
588 ),
589 (Value::Unsigned(5), Value::TextString(String::from("foo"))),
590 (Value::Unsigned(6), Value::ByteString(b"bar".to_vec())),
591 (Value::Unsigned(7), Value::Array(Vec::new())),
592 (
593 Value::Unsigned(8),
594 Value::Array(vec![Value::Unsigned(0), Value::Unsigned(1)]),
595 ),
596 (Value::Unsigned(9), Value::Map(Vec::new())),
597 (
598 Value::Unsigned(10),
599 Value::Map(
600 [(Value::Unsigned(2), Value::Unsigned(3))]
601 .iter()
602 .cloned()
603 .collect(),
604 ),
605 ),
606 ]
607 .iter()
608 .cloned()
609 .collect(),
610 );
611 assert_eq!(a, b);
612 }
613
614 #[test]
615 fn test_cbor_map_collection_empty() {
616 let a = cbor_map_collection!(Vec::<(_, _)>::new());
617 let b = Value::Map(Vec::new());
618 assert_eq!(a, b);
619 }
620
621 #[test]
622 fn test_cbor_map_collection_foo() {
623 let a = cbor_map_collection!(vec![(Value::Unsigned(2), Value::Unsigned(3))]);
624 let b = Value::Map(vec![(Value::Unsigned(2), Value::Unsigned(3))]);
625 assert_eq!(a, b);
626 }
627
628 fn extract_map(cbor_value: Value) -> Vec<(Value, Value)> {
629 match cbor_value {
630 Value::Map(map) => map,
631 _ => panic!("Expected CBOR map."),
632 }
633 }
634
635 #[test]
636 fn test_destructure_cbor_map_simple() {
637 let map = cbor_map! {
638 1 => 10,
639 2 => 20,
640 };
641
642 destructure_cbor_map! {
643 let {
644 1 => x1,
645 2 => x2,
646 } = extract_map(map);
647 }
648
649 assert_eq!(x1, Some(cbor_unsigned!(10)));
650 assert_eq!(x2, Some(cbor_unsigned!(20)));
651 }
652
653 #[test]
654 #[should_panic]
655 fn test_destructure_cbor_map_unsorted() {
656 let map = cbor_map! {
657 1 => 10,
658 2 => 20,
659 };
660
661 destructure_cbor_map! {
662 let {
665 2 => _x2,
666 1 => _x1,
667 } = extract_map(map);
668 }
669 }
670
671 #[test]
672 fn test_destructure_cbor_map_partial() {
673 let map = cbor_map! {
674 1 => 10,
675 2 => 20,
676 3 => 30,
677 4 => 40,
678 5 => 50,
679 6 => 60,
680 7 => 70,
681 8 => 80,
682 9 => 90,
683 };
684
685 destructure_cbor_map! {
686 let {
687 3 => x3,
688 7 => x7,
689 } = extract_map(map);
690 }
691
692 assert_eq!(x3, Some(cbor_unsigned!(30)));
693 assert_eq!(x7, Some(cbor_unsigned!(70)));
694 }
695
696 #[test]
697 fn test_destructure_cbor_map_missing() {
698 let map = cbor_map! {
699 1 => 10,
700 3 => 30,
701 4 => 40,
702 };
703
704 destructure_cbor_map! {
705 let {
706 0 => x0,
707 1 => x1,
708 2 => x2,
709 3 => x3,
710 4 => x4,
711 5 => x5,
712 } = extract_map(map);
713 }
714
715 assert_eq!(x0, None);
716 assert_eq!(x1, Some(cbor_unsigned!(10)));
717 assert_eq!(x2, None);
718 assert_eq!(x3, Some(cbor_unsigned!(30)));
719 assert_eq!(x4, Some(cbor_unsigned!(40)));
720 assert_eq!(x5, None);
721 }
722}