1 //! CBOR values, keys and serialization routines. 2 3 mod de; 4 mod ser; 5 6 use std::cmp::{Ord, Ordering, PartialOrd}; 7 use std::collections::BTreeMap; 8 9 #[doc(inline)] 10 pub use self::de::from_value; 11 #[doc(inline)] 12 pub use self::ser::to_value; 13 14 /// The `Value` enum, a loosely typed way of representing any valid CBOR value. 15 /// 16 /// Maps are sorted according to the canonical ordering 17 /// described in [RFC 7049 bis]. 18 /// Therefore values are unambiguously serialized 19 /// to a canonical form of CBOR from the same RFC. 20 /// 21 /// [RFC 7049 bis]: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-2 22 #[derive(Clone, Debug)] 23 pub enum Value { 24 /// Represents the absence of a value or the value undefined. 25 Null, 26 /// Represents a boolean value. 27 Bool(bool), 28 /// Integer CBOR numbers. 29 /// 30 /// The biggest value that can be represented is 2^64 - 1. 31 /// While the smallest value is -2^64. 32 /// Values outside this range can't be serialized 33 /// and will cause an error. 34 Integer(i128), 35 /// Represents a floating point value. 36 Float(f64), 37 /// Represents a byte string. 38 Bytes(Vec<u8>), 39 /// Represents an UTF-8 encoded string. 40 Text(String), 41 /// Represents an array of values. 42 Array(Vec<Value>), 43 /// Represents a map. 44 /// 45 /// Maps are also called tables, dictionaries, hashes, or objects (in JSON). 46 /// While any value can be used as a CBOR key 47 /// it is better to use only one type of key in a map 48 /// to avoid ambiguity. 49 /// If floating point values are used as keys they are compared bit-by-bit for equality. 50 /// If arrays or maps are used as keys the comparisons 51 /// to establish canonical order may be slow and therefore insertion 52 /// and retrieval of values will be slow too. 53 Map(BTreeMap<Value, Value>), 54 /// Represents a tagged value 55 Tag(u64, Box<Value>), 56 // The hidden variant allows the enum to be extended 57 // with variants for tags and simple values. 58 #[doc(hidden)] 59 __Hidden, 60 } 61 62 impl PartialEq for Value { eq(&self, other: &Value) -> bool63 fn eq(&self, other: &Value) -> bool { 64 self.cmp(other) == Ordering::Equal 65 } 66 } 67 68 impl Eq for Value {} 69 70 impl PartialOrd for Value { partial_cmp(&self, other: &Value) -> Option<Ordering>71 fn partial_cmp(&self, other: &Value) -> Option<Ordering> { 72 Some(self.cmp(other)) 73 } 74 } 75 76 impl Ord for Value { cmp(&self, other: &Value) -> Ordering77 fn cmp(&self, other: &Value) -> Ordering { 78 // Determine the canonical order of two values: 79 // 1. Smaller major type sorts first. 80 // 2. Shorter sequence sorts first. 81 // 3. Compare integers by magnitude. 82 // 4. Compare byte and text sequences lexically. 83 // 5. Compare the serializations of both types. (expensive) 84 use self::Value::*; 85 if self.major_type() != other.major_type() { 86 return self.major_type().cmp(&other.major_type()); 87 } 88 match (self, other) { 89 (Integer(a), Integer(b)) => a.abs().cmp(&b.abs()), 90 (Bytes(a), Bytes(b)) if a.len() != b.len() => a.len().cmp(&b.len()), 91 (Text(a), Text(b)) if a.len() != b.len() => a.len().cmp(&b.len()), 92 (Array(a), Array(b)) if a.len() != b.len() => a.len().cmp(&b.len()), 93 (Map(a), Map(b)) if a.len() != b.len() => a.len().cmp(&b.len()), 94 (Bytes(a), Bytes(b)) => a.cmp(b), 95 (Text(a), Text(b)) => a.cmp(b), 96 (a, b) => { 97 let a = crate::to_vec(a).expect("self is serializable"); 98 let b = crate::to_vec(b).expect("other is serializable"); 99 a.cmp(&b) 100 } 101 } 102 } 103 } 104 105 macro_rules! impl_from { 106 ($variant:path, $for_type:ty) => { 107 impl From<$for_type> for Value { 108 fn from(v: $for_type) -> Value { 109 $variant(v.into()) 110 } 111 } 112 }; 113 } 114 115 impl_from!(Value::Bool, bool); 116 impl_from!(Value::Integer, i8); 117 impl_from!(Value::Integer, i16); 118 impl_from!(Value::Integer, i32); 119 impl_from!(Value::Integer, i64); 120 // i128 omitted because not all numbers fit in CBOR serialization 121 impl_from!(Value::Integer, u8); 122 impl_from!(Value::Integer, u16); 123 impl_from!(Value::Integer, u32); 124 impl_from!(Value::Integer, u64); 125 // u128 omitted because not all numbers fit in CBOR serialization 126 impl_from!(Value::Float, f32); 127 impl_from!(Value::Float, f64); 128 impl_from!(Value::Bytes, Vec<u8>); 129 impl_from!(Value::Text, String); 130 // TODO: figure out if these impls should be more generic or removed. 131 impl_from!(Value::Array, Vec<Value>); 132 impl_from!(Value::Map, BTreeMap<Value, Value>); 133 134 impl Value { major_type(&self) -> u8135 fn major_type(&self) -> u8 { 136 use self::Value::*; 137 match self { 138 Null => 7, 139 Bool(_) => 7, 140 Integer(v) => { 141 if *v >= 0 { 142 0 143 } else { 144 1 145 } 146 } 147 Tag(_, _) => 6, 148 Float(_) => 7, 149 Bytes(_) => 2, 150 Text(_) => 3, 151 Array(_) => 4, 152 Map(_) => 5, 153 __Hidden => unreachable!(), 154 } 155 } 156 } 157