1use alloc::vec;
18use core::{cmp::Ordering, iter::Peekable};
19
20use crate::values::Value;
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 alloc::{string::String, vec, vec::Vec};
366
367 use super::super::values::{SimpleValue, Value};
368
369 #[test]
370 fn test_cbor_simple_values() {
371 assert_eq!(cbor_true!(), Value::Simple(SimpleValue::TrueValue));
372 assert_eq!(cbor_false!(), Value::Simple(SimpleValue::FalseValue));
373 assert_eq!(cbor_null!(), Value::Simple(SimpleValue::NullValue));
374 assert_eq!(cbor_undefined!(), Value::Simple(SimpleValue::Undefined));
375 }
376
377 #[test]
378 fn test_cbor_bool() {
379 assert_eq!(cbor_bool!(true), Value::Simple(SimpleValue::TrueValue));
380 assert_eq!(cbor_bool!(false), Value::Simple(SimpleValue::FalseValue));
381 }
382
383 #[test]
384 fn test_cbor_int_unsigned() {
385 assert_eq!(cbor_int!(0), Value::Unsigned(0));
386 assert_eq!(cbor_int!(1), Value::Unsigned(1));
387 assert_eq!(cbor_int!(123456), Value::Unsigned(123456));
388 assert_eq!(
389 cbor_int!(core::i64::MAX),
390 Value::Unsigned(core::i64::MAX as u64)
391 );
392 }
393
394 #[test]
395 fn test_cbor_int_negative() {
396 assert_eq!(cbor_int!(-1), Value::Negative(-1));
397 assert_eq!(cbor_int!(-123456), Value::Negative(-123456));
398 assert_eq!(
399 cbor_int!(core::i64::MIN),
400 Value::Negative(core::i64::MIN as i128)
401 );
402 }
403
404 #[test]
405 fn test_cbor_int_literals() {
406 let a = cbor_array![
407 core::i64::MIN,
408 core::i32::MIN,
409 -123456,
410 -1,
411 0,
412 1,
413 123456,
414 core::i32::MAX,
415 core::i64::MAX,
416 core::u64::MAX,
417 ];
418 let b = Value::Array(vec![
419 Value::Negative(core::i64::MIN as i128),
420 Value::Negative(core::i32::MIN as i128),
421 Value::Negative(-123456),
422 Value::Negative(-1),
423 Value::Unsigned(0),
424 Value::Unsigned(1),
425 Value::Unsigned(123456),
426 Value::Unsigned(core::i32::MAX as u64),
427 Value::Unsigned(core::i64::MAX as u64),
428 Value::Unsigned(core::u64::MAX),
429 ]);
430 assert_eq!(a, b);
431 }
432
433 #[test]
434 fn test_cbor_array() {
435 let a = cbor_array![
436 -123,
437 456,
438 true,
439 cbor_null!(),
440 "foo",
441 b"bar",
442 cbor_array![],
443 cbor_array![0, 1],
444 cbor_map! {},
445 cbor_map! {2 => 3},
446 ];
447 let b = Value::Array(vec![
448 Value::Negative(-123),
449 Value::Unsigned(456),
450 Value::Simple(SimpleValue::TrueValue),
451 Value::Simple(SimpleValue::NullValue),
452 Value::TextString(String::from("foo")),
453 Value::ByteString(b"bar".to_vec()),
454 Value::Array(Vec::new()),
455 Value::Array(vec![Value::Unsigned(0), Value::Unsigned(1)]),
456 Value::Map(Vec::new()),
457 Value::Map(
458 [(Value::Unsigned(2), Value::Unsigned(3))]
459 .iter()
460 .cloned()
461 .collect(),
462 ),
463 ]);
464 assert_eq!(a, b);
465 }
466
467 #[test]
468 fn test_cbor_array_vec_empty() {
469 let a = cbor_array_vec!(Vec::<bool>::new());
470 let b = Value::Array(Vec::new());
471 assert_eq!(a, b);
472 }
473
474 #[test]
475 fn test_cbor_array_vec_int() {
476 let a = cbor_array_vec!(vec![1, 2, 3, 4]);
477 let b = Value::Array(vec![
478 Value::Unsigned(1),
479 Value::Unsigned(2),
480 Value::Unsigned(3),
481 Value::Unsigned(4),
482 ]);
483 assert_eq!(a, b);
484 }
485
486 #[test]
487 fn test_cbor_array_vec_text() {
488 let a = cbor_array_vec!(vec!["a", "b", "c"]);
489 let b = Value::Array(vec![
490 Value::TextString(String::from("a")),
491 Value::TextString(String::from("b")),
492 Value::TextString(String::from("c")),
493 ]);
494 assert_eq!(a, b);
495 }
496
497 #[test]
498 fn test_cbor_array_vec_bytes() {
499 let a = cbor_array_vec!(vec![b"a", b"b", b"c"]);
500 let b = Value::Array(vec![
501 Value::ByteString(b"a".to_vec()),
502 Value::ByteString(b"b".to_vec()),
503 Value::ByteString(b"c".to_vec()),
504 ]);
505 assert_eq!(a, b);
506 }
507
508 #[test]
509 fn test_cbor_map() {
510 let a = cbor_map! {
511 -1 => -23,
512 4 => 56,
513 "foo" => true,
514 b"bar" => cbor_null!(),
515 5 => "foo",
516 6 => b"bar",
517 7 => cbor_array![],
518 8 => cbor_array![0, 1],
519 9 => cbor_map!{},
520 10 => cbor_map!{2 => 3},
521 };
522 let b = Value::Map(
523 [
524 (Value::Negative(-1), Value::Negative(-23)),
525 (Value::Unsigned(4), Value::Unsigned(56)),
526 (
527 Value::TextString(String::from("foo")),
528 Value::Simple(SimpleValue::TrueValue),
529 ),
530 (
531 Value::ByteString(b"bar".to_vec()),
532 Value::Simple(SimpleValue::NullValue),
533 ),
534 (Value::Unsigned(5), Value::TextString(String::from("foo"))),
535 (Value::Unsigned(6), Value::ByteString(b"bar".to_vec())),
536 (Value::Unsigned(7), Value::Array(Vec::new())),
537 (
538 Value::Unsigned(8),
539 Value::Array(vec![Value::Unsigned(0), Value::Unsigned(1)]),
540 ),
541 (Value::Unsigned(9), Value::Map(Vec::new())),
542 (
543 Value::Unsigned(10),
544 Value::Map(
545 [(Value::Unsigned(2), Value::Unsigned(3))]
546 .iter()
547 .cloned()
548 .collect(),
549 ),
550 ),
551 ]
552 .iter()
553 .cloned()
554 .collect(),
555 );
556 assert_eq!(a, b);
557 }
558
559 #[test]
560 fn test_cbor_map_options() {
561 let a = cbor_map_options! {
562 -1 => -23,
563 4 => Some(56),
564 11 => None::<String>,
565 "foo" => true,
566 12 => None::<&str>,
567 b"bar" => Some(cbor_null!()),
568 13 => None::<Vec<u8>>,
569 5 => "foo",
570 14 => None::<&[u8]>,
571 6 => Some(b"bar" as &[u8]),
572 15 => None::<bool>,
573 7 => cbor_array![],
574 16 => None::<i32>,
575 8 => Some(cbor_array![0, 1]),
576 17 => None::<i64>,
577 9 => cbor_map!{},
578 18 => None::<u64>,
579 10 => Some(cbor_map!{2 => 3}),
580 };
581 let b = Value::Map(
582 [
583 (Value::Negative(-1), Value::Negative(-23)),
584 (Value::Unsigned(4), Value::Unsigned(56)),
585 (
586 Value::TextString(String::from("foo")),
587 Value::Simple(SimpleValue::TrueValue),
588 ),
589 (
590 Value::ByteString(b"bar".to_vec()),
591 Value::Simple(SimpleValue::NullValue),
592 ),
593 (Value::Unsigned(5), Value::TextString(String::from("foo"))),
594 (Value::Unsigned(6), Value::ByteString(b"bar".to_vec())),
595 (Value::Unsigned(7), Value::Array(Vec::new())),
596 (
597 Value::Unsigned(8),
598 Value::Array(vec![Value::Unsigned(0), Value::Unsigned(1)]),
599 ),
600 (Value::Unsigned(9), Value::Map(Vec::new())),
601 (
602 Value::Unsigned(10),
603 Value::Map(
604 [(Value::Unsigned(2), Value::Unsigned(3))]
605 .iter()
606 .cloned()
607 .collect(),
608 ),
609 ),
610 ]
611 .iter()
612 .cloned()
613 .collect(),
614 );
615 assert_eq!(a, b);
616 }
617
618 #[test]
619 fn test_cbor_map_collection_empty() {
620 let a = cbor_map_collection!(Vec::<(_, _)>::new());
621 let b = Value::Map(Vec::new());
622 assert_eq!(a, b);
623 }
624
625 #[test]
626 fn test_cbor_map_collection_foo() {
627 let a = cbor_map_collection!(vec![(Value::Unsigned(2), Value::Unsigned(3))]);
628 let b = Value::Map(vec![(Value::Unsigned(2), Value::Unsigned(3))]);
629 assert_eq!(a, b);
630 }
631
632 fn extract_map(cbor_value: Value) -> Vec<(Value, Value)> {
633 match cbor_value {
634 Value::Map(map) => map,
635 _ => panic!("Expected CBOR map."),
636 }
637 }
638
639 #[test]
640 fn test_destructure_cbor_map_simple() {
641 let map = cbor_map! {
642 1 => 10,
643 2 => 20,
644 };
645
646 destructure_cbor_map! {
647 let {
648 1 => x1,
649 2 => x2,
650 } = extract_map(map);
651 }
652
653 assert_eq!(x1, Some(cbor_unsigned!(10)));
654 assert_eq!(x2, Some(cbor_unsigned!(20)));
655 }
656
657 #[test]
658 #[should_panic]
659 fn test_destructure_cbor_map_unsorted() {
660 let map = cbor_map! {
661 1 => 10,
662 2 => 20,
663 };
664
665 destructure_cbor_map! {
666 let {
669 2 => _x2,
670 1 => _x1,
671 } = extract_map(map);
672 }
673 }
674
675 #[test]
676 fn test_destructure_cbor_map_partial() {
677 let map = cbor_map! {
678 1 => 10,
679 2 => 20,
680 3 => 30,
681 4 => 40,
682 5 => 50,
683 6 => 60,
684 7 => 70,
685 8 => 80,
686 9 => 90,
687 };
688
689 destructure_cbor_map! {
690 let {
691 3 => x3,
692 7 => x7,
693 } = extract_map(map);
694 }
695
696 assert_eq!(x3, Some(cbor_unsigned!(30)));
697 assert_eq!(x7, Some(cbor_unsigned!(70)));
698 }
699
700 #[test]
701 fn test_destructure_cbor_map_missing() {
702 let map = cbor_map! {
703 1 => 10,
704 3 => 30,
705 4 => 40,
706 };
707
708 destructure_cbor_map! {
709 let {
710 0 => x0,
711 1 => x1,
712 2 => x2,
713 3 => x3,
714 4 => x4,
715 5 => x5,
716 } = extract_map(map);
717 }
718
719 assert_eq!(x0, None);
720 assert_eq!(x1, Some(cbor_unsigned!(10)));
721 assert_eq!(x2, None);
722 assert_eq!(x3, Some(cbor_unsigned!(30)));
723 assert_eq!(x4, Some(cbor_unsigned!(40)));
724 assert_eq!(x5, None);
725 }
726}