• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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