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 // https://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 #![allow(deprecated)] 15 /// Represents all the valid types in a flexbuffer. 16 /// 17 /// Flexbuffers supports 18 /// heterogenous maps, heterogenous vectors, typed vectors, and fixed length 19 /// typed vectors for some lengths and types. Rust types are converted into 20 /// Flexbuffers via the [Pushable](trait.Pushable.html) trait. 21 /// 22 /// For exact details see the [internals document]( 23 /// https://google.github.io/flatbuffers/flatbuffers_internals.html) 24 /// 25 /// ### Notes: 26 /// * In the binary format, Each element of a `Map` or (heterogenous) `Vector` 27 /// is stored with a byte describing its FlexBufferType and BitWidth. 28 /// 29 /// * Typed vectors do not store this extra type information and fixed length 30 /// typed vectors do not store length. Whether a vector is stored as a typed 31 /// vector or fixed length typed vector is determined dymaically from the 32 /// given data. 33 /// 34 /// * Indirect numbers are stored as an offset instead of inline. Using 35 /// indirect numbers instead of their inline counterparts in maps and typed 36 /// vectors can reduce the minimum element width and therefore bytes used. 37 38 #[repr(u8)] 39 #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, num_enum::TryFromPrimitive)] 40 pub enum FlexBufferType { 41 /// Nulls are represented with `()` in Rust. 42 Null = 0, 43 /// Variable width signed integer: `i8, i16, i32, i64` 44 Int = 1, 45 /// Variable width unsigned integer: `u8, u16, u32, u64` 46 UInt = 2, 47 /// Variable width floating point: `f32, f64` 48 Float = 3, 49 Bool = 26, 50 /// Null termintated, utf8 string. Typically used with `Map`s. 51 Key = 4, 52 /// Stored with a unsigned integer length, then UTF-8 bytes, and an extra null terminator that 53 /// is not counted with the length. 54 String = 5, 55 /// An Int, stored by offset rather than inline. Indirect types can keep the bitwidth of a 56 /// vector or map small when the inline value would have increased the bitwidth. 57 IndirectInt = 6, 58 /// A UInt, stored by offset rather than inline. Indirect types can keep the bitwidth of a 59 /// vector or map small when the inline value would have increased the bitwidth. 60 IndirectUInt = 7, 61 /// A Float, stored by offset rather than inline. Indirect types can keep the bitwidth of a 62 /// vector or map small when the inline value would have increased the bitwidth. 63 IndirectFloat = 8, 64 /// Maps are like Vectors except elements are associated with, and sorted by, keys. 65 Map = 9, 66 /// Heterogenous Vector (stored with a type table). 67 Vector = 10, 68 /// Homogenous Vector of Ints. 69 VectorInt = 11, 70 /// Homogenous Vector of UInts. 71 VectorUInt = 12, 72 /// Homogenous Vector of Floats. 73 VectorFloat = 13, 74 /// Homogenous Vector of Keys. 75 VectorKey = 14, 76 /// Homogenous Vector of Strings. 77 #[deprecated( 78 note = "Please use Vector or VectorKey instead. See https://github.com/google/flatbuffers/issues/5627" 79 )] 80 VectorString = 15, 81 /// Since the elements of a vector use the same `BitWidth` as the length, 82 /// Blob is more efficient for >255 element boolean vectors. 83 VectorBool = 36, 84 /// Homogenous vector of two Ints 85 VectorInt2 = 16, 86 /// Homogenous vector of two UInts 87 VectorUInt2 = 17, 88 /// Homogenous vector of two Floats 89 VectorFloat2 = 18, 90 /// Homogenous vector of three Ints 91 VectorInt3 = 19, 92 /// Homogenous vector of three UInts 93 VectorUInt3 = 20, 94 /// Homogenous vector of three Floats 95 VectorFloat3 = 21, 96 /// Homogenous vector of four Ints 97 VectorInt4 = 22, 98 /// Homogenous vector of four UInts 99 VectorUInt4 = 23, 100 /// Homogenous vector of four Floats 101 VectorFloat4 = 24, 102 /// An array of bytes. Stored with a variable width length. 103 Blob = 25, 104 } 105 use FlexBufferType::*; 106 107 impl Default for FlexBufferType { default() -> Self108 fn default() -> Self { 109 Null 110 } 111 } 112 113 macro_rules! is_ty { 114 ($is_T: ident, $FTy: ident) => { 115 #[inline(always)] 116 pub fn $is_T(self) -> bool { 117 self == $FTy 118 } 119 }; 120 } 121 122 impl FlexBufferType { 123 /// Returns true for flexbuffer types that are stored inline. is_inline(self) -> bool124 pub fn is_inline(self) -> bool { 125 match self { 126 Null | Int | UInt | Float | Bool => true, 127 _ => false, 128 } 129 } 130 /// Returns true for flexbuffer types that are stored by offset. is_reference(self) -> bool131 pub fn is_reference(self) -> bool { 132 !self.is_inline() 133 } 134 /// Returns true if called on a map, vector, typed vector, or fixed length typed vector. is_vector(self) -> bool135 pub fn is_vector(self) -> bool { 136 let d = self as u8; 137 (9..25).contains(&d) || self == VectorBool 138 } 139 /// True iff the binary format stores the length. 140 /// This applies to Blob, String, Maps, and Vectors of variable length. has_length_slot(self) -> bool141 pub fn has_length_slot(self) -> bool { 142 !self.is_fixed_length_vector() && self.is_vector() || self == String || self == Blob 143 } 144 /// Returns true if called on a fixed length typed vector. is_fixed_length_vector(self) -> bool145 pub fn is_fixed_length_vector(self) -> bool { 146 self.fixed_length_vector_length().is_some() 147 } 148 /// If called on a fixed type vector, returns the type of the elements. typed_vector_type(self) -> Option<FlexBufferType>149 pub fn typed_vector_type(self) -> Option<FlexBufferType> { 150 match self { 151 VectorInt | VectorInt2 | VectorInt3 | VectorInt4 => Some(Int), 152 VectorUInt | VectorUInt2 | VectorUInt3 | VectorUInt4 => Some(UInt), 153 VectorFloat | VectorFloat2 | VectorFloat3 | VectorFloat4 => Some(Float), 154 VectorKey => Some(Key), 155 // Treat them as keys because we do not know width of length slot. 156 // see deprecation link. 157 VectorString => Some(Key), 158 VectorBool => Some(Bool), 159 _ => None, 160 } 161 } 162 /// Return the length of the fixed length vector or None. fixed_length_vector_length(self) -> Option<usize>163 pub fn fixed_length_vector_length(self) -> Option<usize> { 164 match self { 165 VectorInt2 | VectorUInt2 | VectorFloat2 => Some(2), 166 VectorInt3 | VectorUInt3 | VectorFloat3 => Some(3), 167 VectorInt4 | VectorUInt4 | VectorFloat4 => Some(4), 168 _ => None, 169 } 170 } 171 /// Returns true if self is a Map or Vector. Typed vectors are not heterogenous. is_heterogenous(self) -> bool172 pub fn is_heterogenous(self) -> bool { 173 self == Map || self == Vector 174 } 175 /// If `self` is an indirect scalar, remap it to the scalar. Otherwise do nothing. to_direct(self) -> Option<Self>176 pub fn to_direct(self) -> Option<Self> { 177 match self { 178 IndirectInt => Some(Int), 179 IndirectUInt => Some(UInt), 180 IndirectFloat => Some(Float), 181 _ => None, 182 } 183 } 184 // returns true if and only if the flexbuffer type is `Null`. 185 is_ty!(is_null, Null); 186 // returns true if and only if the flexbuffer type is `Int`. 187 is_ty!(is_int, Int); 188 // returns true if and only if the flexbuffer type is `UInt`. 189 is_ty!(is_uint, UInt); 190 // returns true if and only if the flexbuffer type is `Float`. 191 is_ty!(is_float, Float); 192 // returns true if and only if the flexbuffer type is `Bool`. 193 is_ty!(is_bool, Bool); 194 // returns true if and only if the flexbuffer type is `Key`. 195 is_ty!(is_key, Key); 196 // returns true if and only if the flexbuffer type is `String`. 197 is_ty!(is_string, String); 198 // returns true if and only if the flexbuffer type is `IndirectInt`. 199 is_ty!(is_indirect_int, IndirectInt); 200 // returns true if and only if the flexbuffer type is `IndirectUInt`. 201 is_ty!(is_indirect_uint, IndirectUInt); 202 // returns true if and only if the flexbuffer type is `IndirectFloat`. 203 is_ty!(is_indirect_float, IndirectFloat); 204 // returns true if and only if the flexbuffer type is `Map`. 205 is_ty!(is_map, Map); 206 // returns true if and only if the flexbuffer type is `Vector`. 207 is_ty!(is_heterogenous_vector, Vector); 208 // returns true if and only if the flexbuffer type is `VectorInt`. 209 is_ty!(is_vector_int, VectorInt); 210 // returns true if and only if the flexbuffer type is `VectorUInt`. 211 is_ty!(is_vector_uint, VectorUInt); 212 // returns true if and only if the flexbuffer type is `VectorFloat`. 213 is_ty!(is_vector_float, VectorFloat); 214 // returns true if and only if the flexbuffer type is `VectorKey`. 215 is_ty!(is_vector_key, VectorKey); 216 // returns true if and only if the flexbuffer type is `VectorString`. 217 is_ty!(is_vector_string, VectorString); 218 // returns true if and only if the flexbuffer type is `VectorBool`. 219 is_ty!(is_vector_bool, VectorBool); 220 // returns true if and only if the flexbuffer type is `VectorInt2`. 221 is_ty!(is_vector_int2, VectorInt2); 222 // returns true if and only if the flexbuffer type is `VectorUInt2`. 223 is_ty!(is_vector_uint2, VectorUInt2); 224 // returns true if and only if the flexbuffer type is `VectorFloat2`. 225 is_ty!(is_vector_float2, VectorFloat2); 226 // returns true if and only if the flexbuffer type is `VectorInt3`. 227 is_ty!(is_vector_int3, VectorInt3); 228 // returns true if and only if the flexbuffer type is `VectorUInt3`. 229 is_ty!(is_vector_uint3, VectorUInt3); 230 // returns true if and only if the flexbuffer type is `VectorFloat3`. 231 is_ty!(is_vector_float3, VectorFloat3); 232 // returns true if and only if the flexbuffer type is `VectorInt4`. 233 is_ty!(is_vector_int4, VectorInt4); 234 // returns true if and only if the flexbuffer type is `VectorUInt4`. 235 is_ty!(is_vector_uint4, VectorUInt4); 236 // returns true if and only if the flexbuffer type is `VectorFloat4`. 237 is_ty!(is_vector_float4, VectorFloat4); 238 // returns true if and only if the flexbuffer type is `Blob`. 239 is_ty!(is_blob, Blob); 240 } 241