Skip to main content

sk_cbor/
values.rs

1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Types for expressing CBOR values.
16
17use alloc::boxed::Box;
18use alloc::string::{String, ToString};
19use alloc::vec::Vec;
20use core::cmp::Ordering;
21
22/// The CBOR data structure.
23#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
24pub struct Value(pub(crate) ValueImpl);
25
26/// Possible CBOR values.
27#[derive(Clone, Debug)]
28pub(crate) enum ValueImpl {
29    /// Unsigned integer value (uint).
30    Unsigned(u64),
31    /// Signed integer value (nint). Only 63 bits of information are used here.
32    Negative(i64),
33    /// Byte string (bstr).
34    ByteString(Vec<u8>),
35    /// Text string (tstr).
36    TextString(String),
37    /// Array/tuple of values.
38    Array(Vec<Value>),
39    /// Map of key-value pairs.
40    Map(Vec<(Value, Value)>),
41    /// Tagged value.
42    Tag(u64, Box<Value>),
43    /// Simple value.
44    Simple(SimpleValue),
45}
46
47/// Specific simple CBOR values.
48#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
49pub(crate) enum SimpleValue {
50    FalseValue = 20,
51    TrueValue = 21,
52    NullValue = 22,
53    Undefined = 23,
54}
55
56/// Constant values required for CBOR encoding.
57pub struct Constants {}
58
59impl Constants {
60    /// Number of bits used to shift left the major type of a CBOR type byte.
61    pub const MAJOR_TYPE_BIT_SHIFT: u8 = 5;
62    /// Mask to retrieve the additional information held in a CBOR type bytes,
63    /// ignoring the major type.
64    pub const ADDITIONAL_INFORMATION_MASK: u8 = 0x1F;
65    /// Additional information value that indicates the largest inline value.
66    pub const ADDITIONAL_INFORMATION_MAX_INT: u8 = 23;
67    /// Additional information value indicating that a 1-byte length follows.
68    pub const ADDITIONAL_INFORMATION_1_BYTE: u8 = 24;
69    /// Additional information value indicating that a 2-byte length follows.
70    pub const ADDITIONAL_INFORMATION_2_BYTES: u8 = 25;
71    /// Additional information value indicating that a 4-byte length follows.
72    pub const ADDITIONAL_INFORMATION_4_BYTES: u8 = 26;
73    /// Additional information value indicating that an 8-byte length follows.
74    pub const ADDITIONAL_INFORMATION_8_BYTES: u8 = 27;
75}
76
77impl Value {
78    /// Creates a CBOR unsigned value.
79    pub fn unsigned(int: u64) -> Value {
80        Value(ValueImpl::Unsigned(int))
81    }
82
83    /// Create an appropriate CBOR integer value (uint/nint).
84    /// For simplicity, this only takes i64. Construct directly for the last bit.
85    pub fn integer(int: i64) -> Value {
86        if int >= 0 {
87            Value(ValueImpl::Unsigned(int as u64))
88        } else {
89            Value(ValueImpl::Negative(int))
90        }
91    }
92
93    /// Creates a CBOR byte string value.
94    pub fn byte_string(bytes: Vec<u8>) -> Value {
95        Value(ValueImpl::ByteString(bytes))
96    }
97
98    /// Creates a CBOR text string value.
99    pub fn text_string(text: String) -> Value {
100        Value(ValueImpl::TextString(text))
101    }
102
103    /// Create a CBOR array value.
104    pub fn array(a: Vec<Value>) -> Value {
105        Value(ValueImpl::Array(a))
106    }
107
108    /// Create a CBOR map value.
109    ///
110    /// Keys do not have to be sorted.
111    ///
112    /// # Panics
113    ///
114    /// You may not call this function with identical keys in its argument.
115    pub fn map(mut m: Vec<(Value, Value)>) -> Value {
116        m.sort_by(|a, b| a.0.cmp(&b.0));
117        let map_len = m.len();
118        m.dedup_by(|a, b| a.0.eq(&b.0));
119        if map_len != m.len() {
120            panic!();
121        }
122        Value(ValueImpl::Map(m))
123    }
124
125    /// Create a CBOR tagged value.
126    pub fn tag(int: u64, value: Value) -> Value {
127        Value(ValueImpl::Tag(int, Box::new(value)))
128    }
129
130    /// Create a CBOR boolean simple value.
131    pub fn bool_value(b: bool) -> Value {
132        if b {
133            Value(ValueImpl::Simple(SimpleValue::TrueValue))
134        } else {
135            Value(ValueImpl::Simple(SimpleValue::FalseValue))
136        }
137    }
138
139    /// Creates a null value.
140    pub fn null_value() -> Value {
141        Value(ValueImpl::Simple(SimpleValue::NullValue))
142    }
143
144    /// Creates an undefined value.
145    pub fn undefined() -> Value {
146        Value(ValueImpl::Simple(SimpleValue::Undefined))
147    }
148
149    pub fn extract_unsigned(self) -> Option<u64> {
150        match self {
151            Value(ValueImpl::Unsigned(unsigned)) => Some(unsigned),
152            _ => None,
153        }
154    }
155
156    pub fn extract_integer(self) -> Option<i64> {
157        match self {
158            Value(ValueImpl::Unsigned(unsigned)) => {
159                if unsigned <= i64::MAX as u64 {
160                    Some(unsigned as i64)
161                } else {
162                    None
163                }
164            }
165            Value(ValueImpl::Negative(signed)) => Some(signed),
166            _ => None,
167        }
168    }
169
170    pub fn extract_byte_string(self) -> Option<Vec<u8>> {
171        match self {
172            Value(ValueImpl::ByteString(byte_string)) => Some(byte_string),
173            _ => None,
174        }
175    }
176
177    pub fn extract_text_string(self) -> Option<String> {
178        match self {
179            Value(ValueImpl::TextString(text_string)) => Some(text_string),
180            _ => None,
181        }
182    }
183
184    pub fn extract_array(self) -> Option<Vec<Value>> {
185        match self {
186            Value(ValueImpl::Array(array)) => Some(array),
187            _ => None,
188        }
189    }
190
191    pub fn extract_map(self) -> Option<Vec<(Value, Value)>> {
192        match self {
193            Value(ValueImpl::Map(map)) => Some(map),
194            _ => None,
195        }
196    }
197
198    pub fn extract_tag(self) -> Option<(u64, Value)> {
199        match self {
200            Value(ValueImpl::Tag(tag, value)) => Some((tag, *value)),
201            _ => None,
202        }
203    }
204
205    pub fn extract_bool(self) -> Option<bool> {
206        match self {
207            Value(ValueImpl::Simple(SimpleValue::FalseValue)) => Some(false),
208            Value(ValueImpl::Simple(SimpleValue::TrueValue)) => Some(true),
209            _ => None,
210        }
211    }
212
213    pub fn extract_null(self) -> Option<()> {
214        match self {
215            Value(ValueImpl::Simple(SimpleValue::NullValue)) => Some(()),
216            _ => None,
217        }
218    }
219
220    pub fn extract_undefined(self) -> Option<()> {
221        match self {
222            Value(ValueImpl::Simple(SimpleValue::Undefined)) => Some(()),
223            _ => None,
224        }
225    }
226}
227
228impl ValueImpl {
229    /// Return the major type for the [`ValueImpl`].
230    pub fn type_label(&self) -> u8 {
231        // TODO use enum discriminant instead when stable
232        // https://github.com/rust-lang/rust/issues/60553
233        match self {
234            ValueImpl::Unsigned(_) => 0,
235            ValueImpl::Negative(_) => 1,
236            ValueImpl::ByteString(_) => 2,
237            ValueImpl::TextString(_) => 3,
238            ValueImpl::Array(_) => 4,
239            ValueImpl::Map(_) => 5,
240            ValueImpl::Tag(_, _) => 6,
241            ValueImpl::Simple(_) => 7,
242        }
243    }
244}
245
246impl Ord for ValueImpl {
247    fn cmp(&self, other: &ValueImpl) -> Ordering {
248        use super::values::ValueImpl::{
249            Array, ByteString, Map, Negative, Simple, Tag, TextString, Unsigned,
250        };
251        let self_type_value = self.type_label();
252        let other_type_value = other.type_label();
253        if self_type_value != other_type_value {
254            return self_type_value.cmp(&other_type_value);
255        }
256        match (self, other) {
257            (Unsigned(u1), Unsigned(u2)) => u1.cmp(u2),
258            (Negative(n1), Negative(n2)) => n1.cmp(n2).reverse(),
259            (ByteString(b1), ByteString(b2)) => b1.len().cmp(&b2.len()).then(b1.cmp(b2)),
260            (TextString(t1), TextString(t2)) => t1.len().cmp(&t2.len()).then(t1.cmp(t2)),
261            (Array(a1), Array(a2)) if a1.len() != a2.len() => a1.len().cmp(&a2.len()),
262            (Array(a1), Array(a2)) => {
263                // Arrays of same length.
264                let mut ordering = Ordering::Equal;
265                for (e1, e2) in a1.iter().zip(a2.iter()) {
266                    ordering = e1.cmp(e2);
267                    if !matches!(ordering, Ordering::Equal) {
268                        break;
269                    }
270                }
271                ordering
272            }
273            (Map(m1), Map(m2)) if m1.len() != m2.len() => m1.len().cmp(&m2.len()),
274            (Map(m1), Map(m2)) => {
275                // Maps of same length.
276                let mut ordering = Ordering::Equal;
277                for ((k1, v1), (k2, v2)) in m1.iter().zip(m2.iter()) {
278                    ordering = k1.cmp(k2).then_with(|| v1.cmp(v2));
279                    if !matches!(ordering, Ordering::Equal) {
280                        break;
281                    }
282                }
283                ordering
284            }
285            (Tag(t1, v1), Tag(t2, v2)) => t1.cmp(t2).then(v1.cmp(v2)),
286            (Simple(s1), Simple(s2)) => s1.cmp(s2),
287            (_, _) => {
288                // The case of different major types is caught above.
289                unreachable!();
290            }
291        }
292    }
293}
294
295impl PartialOrd for ValueImpl {
296    fn partial_cmp(&self, other: &ValueImpl) -> Option<Ordering> {
297        Some(self.cmp(other))
298    }
299}
300
301impl Eq for ValueImpl {}
302
303impl PartialEq for ValueImpl {
304    fn eq(&self, other: &ValueImpl) -> bool {
305        self.cmp(other) == Ordering::Equal
306    }
307}
308
309impl SimpleValue {
310    /// Create a simple value from its encoded value.
311    pub fn from_integer(int: u64) -> Option<SimpleValue> {
312        match int {
313            20 => Some(SimpleValue::FalseValue),
314            21 => Some(SimpleValue::TrueValue),
315            22 => Some(SimpleValue::NullValue),
316            23 => Some(SimpleValue::Undefined),
317            _ => None,
318        }
319    }
320}
321
322impl From<u64> for Value {
323    fn from(u: u64) -> Self {
324        Value::unsigned(u)
325    }
326}
327
328impl From<u32> for Value {
329    fn from(u: u32) -> Self {
330        Value::unsigned(u as u64)
331    }
332}
333
334impl From<u16> for Value {
335    fn from(u: u16) -> Self {
336        Value::unsigned(u as u64)
337    }
338}
339
340impl From<u8> for Value {
341    fn from(u: u8) -> Self {
342        Value::unsigned(u as u64)
343    }
344}
345
346impl From<i64> for Value {
347    fn from(i: i64) -> Self {
348        Value::integer(i)
349    }
350}
351
352impl From<i32> for Value {
353    fn from(i: i32) -> Self {
354        Value::integer(i as i64)
355    }
356}
357
358impl From<i16> for Value {
359    fn from(i: i16) -> Self {
360        Value::integer(i as i64)
361    }
362}
363
364impl From<i8> for Value {
365    fn from(i: i8) -> Self {
366        Value::integer(i as i64)
367    }
368}
369
370impl From<Vec<u8>> for Value {
371    fn from(bytes: Vec<u8>) -> Self {
372        Value(ValueImpl::ByteString(bytes))
373    }
374}
375
376impl From<&[u8]> for Value {
377    fn from(bytes: &[u8]) -> Self {
378        Value(ValueImpl::ByteString(bytes.to_vec()))
379    }
380}
381
382impl From<&[u8; 0]> for Value {
383    fn from(bytes: &[u8; 0]) -> Self {
384        Value(ValueImpl::ByteString(bytes.to_vec()))
385    }
386}
387
388impl From<String> for Value {
389    fn from(text: String) -> Self {
390        Value(ValueImpl::TextString(text))
391    }
392}
393
394impl From<&str> for Value {
395    fn from(text: &str) -> Self {
396        Value(ValueImpl::TextString(text.to_string()))
397    }
398}
399
400impl From<Vec<Value>> for Value {
401    fn from(array: Vec<Value>) -> Self {
402        Value(ValueImpl::Array(array))
403    }
404}
405
406impl From<Vec<(Value, Value)>> for Value {
407    fn from(map: Vec<(Value, Value)>) -> Self {
408        Value::map(map)
409    }
410}
411
412impl From<bool> for Value {
413    fn from(b: bool) -> Self {
414        Value::bool_value(b)
415    }
416}
417
418/// Trait that indicates that a type can be converted to a CBOR [`Value`].
419pub trait IntoCborValue {
420    /// Convert `self` into a CBOR [`Value`], consuming it along the way.
421    fn into_cbor_value(self) -> Value;
422}
423
424impl<T> IntoCborValue for T
425where
426    Value: From<T>,
427{
428    fn into_cbor_value(self) -> Value {
429        Value::from(self)
430    }
431}
432
433/// Trait that indicates that a type can be converted to a CBOR [`Option<Value>`].
434pub trait IntoCborValueOption {
435    /// Convert `self` into a CBOR [`Option<Value>`], consuming it along the way.
436    fn into_cbor_value_option(self) -> Option<Value>;
437}
438
439impl<T> IntoCborValueOption for T
440where
441    Value: From<T>,
442{
443    fn into_cbor_value_option(self) -> Option<Value> {
444        Some(Value::from(self))
445    }
446}
447
448impl<T> IntoCborValueOption for Option<T>
449where
450    Value: From<T>,
451{
452    fn into_cbor_value_option(self) -> Option<Value> {
453        self.map(Value::from)
454    }
455}
456
457#[cfg(test)]
458mod test {
459    use super::*;
460    use crate::{
461        cbor_array, cbor_bool, cbor_bytes, cbor_bytes_lit, cbor_int, cbor_map, cbor_null,
462        cbor_tagged, cbor_text, cbor_undefined, cbor_unsigned,
463    };
464    use alloc::vec;
465
466    #[test]
467    #[should_panic]
468    fn test_duplicate_map_key() {
469        let _map = cbor_map! {
470            0 => "a",
471            -1 => "c",
472            b"a" => "e",
473            "c" => "g",
474            0 => "b",
475        };
476    }
477
478    #[test]
479    fn test_extract_unsigned() {
480        assert_eq!(cbor_int!(1).extract_unsigned(), Some(1));
481        assert_eq!(cbor_int!(-1).extract_unsigned(), None);
482        assert_eq!(cbor_bytes!(vec![]).extract_unsigned(), None);
483        assert_eq!(cbor_text!("").extract_unsigned(), None);
484        assert_eq!(cbor_array![].extract_unsigned(), None);
485        assert_eq!(cbor_map! {}.extract_unsigned(), None);
486        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_unsigned(), None);
487        assert_eq!(cbor_bool!(false).extract_unsigned(), None);
488    }
489
490    #[test]
491    fn test_extract_unsigned_limits() {
492        assert_eq!(
493            cbor_unsigned!(core::u64::MAX).extract_unsigned(),
494            Some(core::u64::MAX)
495        );
496        assert_eq!(
497            cbor_unsigned!((core::i64::MAX as u64) + 1).extract_unsigned(),
498            Some((core::i64::MAX as u64) + 1)
499        );
500        assert_eq!(
501            cbor_int!(core::i64::MAX).extract_unsigned(),
502            Some(core::i64::MAX as u64)
503        );
504        assert_eq!(cbor_int!(123).extract_unsigned(), Some(123));
505        assert_eq!(cbor_int!(0).extract_unsigned(), Some(0));
506        assert_eq!(cbor_int!(-123).extract_unsigned(), None);
507        assert_eq!(cbor_int!(core::i64::MIN).extract_unsigned(), None);
508    }
509
510    #[test]
511    fn test_extract_integer() {
512        assert_eq!(cbor_int!(1).extract_integer(), Some(1));
513        assert_eq!(cbor_int!(-1).extract_integer(), Some(-1));
514        assert_eq!(cbor_bytes!(vec![]).extract_integer(), None);
515        assert_eq!(cbor_text!("").extract_integer(), None);
516        assert_eq!(cbor_array![].extract_integer(), None);
517        assert_eq!(cbor_map! {}.extract_integer(), None);
518        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_integer(), None);
519        assert_eq!(cbor_bool!(false).extract_integer(), None);
520    }
521
522    #[test]
523    fn test_extract_integer_limits() {
524        assert_eq!(cbor_unsigned!(core::u64::MAX).extract_integer(), None);
525        assert_eq!(
526            cbor_unsigned!((core::i64::MAX as u64) + 1).extract_integer(),
527            None
528        );
529        assert_eq!(
530            cbor_int!(core::i64::MAX).extract_integer(),
531            Some(core::i64::MAX)
532        );
533        assert_eq!(cbor_int!(123).extract_integer(), Some(123));
534        assert_eq!(cbor_int!(0).extract_integer(), Some(0));
535        assert_eq!(cbor_int!(-123).extract_integer(), Some(-123));
536        assert_eq!(
537            cbor_int!(core::i64::MIN).extract_integer(),
538            Some(core::i64::MIN)
539        );
540    }
541
542    #[test]
543    fn test_extract_byte_string() {
544        assert_eq!(cbor_int!(1).extract_byte_string(), None);
545        assert_eq!(cbor_int!(-1).extract_byte_string(), None);
546        assert_eq!(cbor_bytes!(vec![]).extract_byte_string(), Some(Vec::new()));
547        assert_eq!(
548            cbor_bytes_lit!(b"bar").extract_byte_string(),
549            Some(b"bar".to_vec())
550        );
551        assert_eq!(cbor_text!("").extract_byte_string(), None);
552        assert_eq!(cbor_array![].extract_byte_string(), None);
553        assert_eq!(cbor_map! {}.extract_byte_string(), None);
554        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_byte_string(), None);
555        assert_eq!(cbor_bool!(false).extract_byte_string(), None);
556    }
557
558    #[test]
559    fn test_extract_text_string() {
560        assert_eq!(cbor_int!(1).extract_text_string(), None);
561        assert_eq!(cbor_int!(-1).extract_text_string(), None);
562        assert_eq!(cbor_bytes!(vec![]).extract_text_string(), None);
563        assert_eq!(cbor_text!("").extract_text_string(), Some(String::new()));
564        assert_eq!(cbor_text!("s").extract_text_string(), Some("s".to_string()));
565        assert_eq!(cbor_array![].extract_text_string(), None);
566        assert_eq!(cbor_map! {}.extract_text_string(), None);
567        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_text_string(), None);
568        assert_eq!(cbor_bool!(false).extract_text_string(), None);
569    }
570
571    #[test]
572    fn test_extract_array() {
573        assert_eq!(cbor_int!(1).extract_array(), None);
574        assert_eq!(cbor_int!(-1).extract_array(), None);
575        assert_eq!(cbor_bytes!(vec![]).extract_array(), None);
576        assert_eq!(cbor_text!("").extract_array(), None);
577        assert_eq!(cbor_array![].extract_array(), Some(Vec::new()));
578        assert_eq!(
579            cbor_array![cbor_int!(1)].extract_array(),
580            Some(vec![cbor_int!(1)])
581        );
582        assert_eq!(cbor_map! {}.extract_array(), None);
583        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_array(), None);
584        assert_eq!(cbor_bool!(false).extract_array(), None);
585    }
586
587    #[test]
588    fn test_extract_map() {
589        assert_eq!(cbor_int!(1).extract_map(), None);
590        assert_eq!(cbor_int!(-1).extract_map(), None);
591        assert_eq!(cbor_bytes!(vec![]).extract_map(), None);
592        assert_eq!(cbor_text!("").extract_map(), None);
593        assert_eq!(cbor_array![].extract_map(), None);
594        assert_eq!(cbor_map! {}.extract_map(), Some(Vec::new()));
595        assert_eq!(
596            cbor_map! {0 => 1}.extract_map(),
597            Some(vec![(cbor_int!(0), cbor_int!(1))])
598        );
599        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_map(), None);
600        assert_eq!(cbor_bool!(false).extract_map(), None);
601    }
602
603    #[test]
604    fn test_extract_tag() {
605        assert_eq!(cbor_int!(1).extract_tag(), None);
606        assert_eq!(cbor_int!(-1).extract_tag(), None);
607        assert_eq!(cbor_bytes!(vec![]).extract_tag(), None);
608        assert_eq!(cbor_text!("").extract_tag(), None);
609        assert_eq!(cbor_array![].extract_tag(), None);
610        assert_eq!(cbor_map! {}.extract_tag(), None);
611        assert_eq!(
612            cbor_tagged!(1, cbor_text!("s")).extract_tag(),
613            Some((1, cbor_text!("s")))
614        );
615        assert_eq!(cbor_bool!(false).extract_tag(), None);
616    }
617
618    #[test]
619    fn test_extract_bool() {
620        assert_eq!(cbor_int!(1).extract_bool(), None);
621        assert_eq!(cbor_int!(-1).extract_bool(), None);
622        assert_eq!(cbor_bytes!(vec![]).extract_bool(), None);
623        assert_eq!(cbor_text!("").extract_bool(), None);
624        assert_eq!(cbor_array![].extract_bool(), None);
625        assert_eq!(cbor_map! {}.extract_bool(), None);
626        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_bool(), None);
627        assert_eq!(cbor_bool!(false).extract_bool(), Some(false));
628        assert_eq!(cbor_bool!(true).extract_bool(), Some(true));
629        assert_eq!(cbor_null!().extract_bool(), None);
630        assert_eq!(cbor_undefined!().extract_bool(), None);
631    }
632
633    #[test]
634    fn test_extract_null() {
635        assert_eq!(cbor_int!(1).extract_null(), None);
636        assert_eq!(cbor_int!(-1).extract_null(), None);
637        assert_eq!(cbor_bytes!(vec![]).extract_null(), None);
638        assert_eq!(cbor_text!("").extract_null(), None);
639        assert_eq!(cbor_array![].extract_null(), None);
640        assert_eq!(cbor_map! {}.extract_null(), None);
641        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_null(), None);
642        assert_eq!(cbor_bool!(false).extract_null(), None);
643        assert_eq!(cbor_bool!(true).extract_null(), None);
644        assert_eq!(cbor_null!().extract_null(), Some(()));
645        assert_eq!(cbor_undefined!().extract_null(), None);
646    }
647
648    #[test]
649    fn test_extract_undefined() {
650        assert_eq!(cbor_int!(1).extract_undefined(), None);
651        assert_eq!(cbor_int!(-1).extract_undefined(), None);
652        assert_eq!(cbor_bytes!(vec![]).extract_undefined(), None);
653        assert_eq!(cbor_text!("").extract_undefined(), None);
654        assert_eq!(cbor_array![].extract_undefined(), None);
655        assert_eq!(cbor_map! {}.extract_undefined(), None);
656        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_undefined(), None);
657        assert_eq!(cbor_bool!(false).extract_undefined(), None);
658        assert_eq!(cbor_bool!(true).extract_undefined(), None);
659        assert_eq!(cbor_null!().extract_undefined(), None);
660        assert_eq!(cbor_undefined!().extract_undefined(), Some(()));
661    }
662
663    #[test]
664    fn test_value_ordering() {
665        assert!(cbor_int!(0) < cbor_int!(23));
666        assert!(cbor_int!(23) < cbor_int!(24));
667        assert!(cbor_int!(24) < cbor_int!(1000));
668        assert!(cbor_int!(1000) < cbor_int!(1000000));
669        assert!(cbor_int!(1000000) < cbor_int!(core::i64::MAX));
670        assert!(cbor_int!(core::i64::MAX) < cbor_int!(-1));
671        assert!(cbor_int!(-1) < cbor_int!(-23));
672        assert!(cbor_int!(-23) < cbor_int!(-24));
673        assert!(cbor_int!(-24) < cbor_int!(-1000));
674        assert!(cbor_int!(-1000) < cbor_int!(-1000000));
675        assert!(cbor_int!(-1000000) < cbor_int!(core::i64::MIN));
676        assert!(cbor_int!(core::i64::MIN) < cbor_bytes!(vec![]));
677        assert!(cbor_bytes!(vec![]) < cbor_bytes!(vec![0x00]));
678        assert!(cbor_bytes!(vec![0x00]) < cbor_bytes!(vec![0x01]));
679        assert!(cbor_bytes!(vec![0x01]) < cbor_bytes!(vec![0xFF]));
680        assert!(cbor_bytes!(vec![0xFF]) < cbor_bytes!(vec![0x00, 0x00]));
681        assert!(cbor_bytes!(vec![0x00, 0x00]) < cbor_text!(""));
682        assert!(cbor_text!("") < cbor_text!("a"));
683        assert!(cbor_text!("a") < cbor_text!("b"));
684        assert!(cbor_text!("b") < cbor_text!("aa"));
685        assert!(cbor_text!("aa") < cbor_array![]);
686        assert!(cbor_array![] < cbor_array![0]);
687        assert!(cbor_array![0] < cbor_array![-1]);
688        assert!(cbor_array![1] < cbor_array![b""]);
689        assert!(cbor_array![b""] < cbor_array![""]);
690        assert!(cbor_array![""] < cbor_array![cbor_array![]]);
691        assert!(cbor_array![cbor_array![]] < cbor_array![cbor_map! {}]);
692        assert!(cbor_array![cbor_map! {}] < cbor_array![false]);
693        assert!(cbor_array![false] < cbor_array![0, 0]);
694        assert!(cbor_array![0, 1] < cbor_array![0, 2]);
695        assert!(cbor_array![0, 0] < cbor_map! {});
696        assert!(cbor_map! {} < cbor_map! {0 => 0});
697        assert!(cbor_map! {0 => 0} < cbor_map! {0 => 1});
698        assert!(cbor_map! {0 => 1} < cbor_map! {1 => 0});
699        assert!(cbor_map! {1 => 0} < cbor_map! {-1 => 0});
700        assert!(cbor_map! {-1 => 0} < cbor_map! {b"" => 0});
701        assert!(cbor_map! {b"" => 0} < cbor_map! {"" => 0});
702        assert!(cbor_map! {"" => 0} < cbor_map! {cbor_array![] => 0});
703        assert!(cbor_map! {cbor_array![] => 0} < cbor_map! {cbor_map!{} => 0});
704        assert!(cbor_map! {cbor_map!{} => 0} < cbor_map! {false => 0});
705        assert!(cbor_map! {false => 0} < cbor_map! {0 => 0, 1 => 0});
706        assert!(cbor_map! {0 => 0, 1 => 1} < cbor_map! {0 => 0, 1 => 2});
707        assert!(cbor_map! {0 => 0} < cbor_tagged!(2, cbor_int!(0)));
708        assert!(cbor_map! {0 => 0, 1 => 0} < cbor_bool!(false));
709        assert!(cbor_bool!(false) < cbor_bool!(true));
710        assert!(cbor_bool!(true) < cbor_null!());
711        assert!(cbor_null!() < cbor_undefined!());
712        assert!(cbor_tagged!(1, cbor_text!("s")) < cbor_tagged!(2, cbor_int!(0)));
713        assert!(cbor_tagged!(1, cbor_unsigned!(0)) < cbor_tagged!(1, cbor_unsigned!(1)));
714        assert!(cbor_int!(1) < cbor_int!(-1));
715        assert!(cbor_int!(1) < cbor_bytes!(vec![0x00]));
716        assert!(cbor_int!(1) < cbor_text!("s"));
717        assert!(cbor_int!(1) < cbor_array![]);
718        assert!(cbor_int!(1) < cbor_map! {});
719        assert!(cbor_int!(1) < cbor_tagged!(1, cbor_text!("s")));
720        assert!(cbor_int!(1) < cbor_bool!(false));
721        assert!(cbor_int!(-1) < cbor_bytes!(vec![0x00]));
722        assert!(cbor_int!(-1) < cbor_text!("s"));
723        assert!(cbor_int!(-1) < cbor_array![]);
724        assert!(cbor_int!(-1) < cbor_map! {});
725        assert!(cbor_int!(-1) < cbor_tagged!(1, cbor_text!("s")));
726        assert!(cbor_int!(-1) < cbor_bool!(false));
727        assert!(cbor_bytes!(vec![0x00]) < cbor_text!("s"));
728        assert!(cbor_bytes!(vec![0x00]) < cbor_array![]);
729        assert!(cbor_bytes!(vec![0x00]) < cbor_map! {});
730        assert!(cbor_bytes!(vec![0x00]) < cbor_tagged!(1, cbor_text!("s")));
731        assert!(cbor_bytes!(vec![0x00]) < cbor_bool!(false));
732        assert!(cbor_text!("s") < cbor_array![]);
733        assert!(cbor_text!("s") < cbor_map! {});
734        assert!(cbor_text!("s") < cbor_tagged!(1, cbor_text!("s")));
735        assert!(cbor_text!("s") < cbor_bool!(false));
736        assert!(cbor_array![] < cbor_map!(0 => 1));
737        assert!(cbor_array![] < cbor_tagged!(2, cbor_int!(0)));
738        assert!(cbor_array![] < cbor_bool!(false));
739        assert!(cbor_tagged!(1, cbor_text!("s")) < cbor_bool!(false));
740    }
741}