xref: /aosp_15_r20/external/flatbuffers/rust/flexbuffers/src/builder/value.rs (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Worker // Copyright 2019 Google LLC
2*890232f2SAndroid Build Coastguard Worker //
3*890232f2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*890232f2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*890232f2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*890232f2SAndroid Build Coastguard Worker //
7*890232f2SAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*890232f2SAndroid Build Coastguard Worker //
9*890232f2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*890232f2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*890232f2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*890232f2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*890232f2SAndroid Build Coastguard Worker // limitations under the License.
14*890232f2SAndroid Build Coastguard Worker 
15*890232f2SAndroid Build Coastguard Worker use byteorder::{LittleEndian, WriteBytesExt};
16*890232f2SAndroid Build Coastguard Worker 
17*890232f2SAndroid Build Coastguard Worker use crate::bitwidth::BitWidth;
18*890232f2SAndroid Build Coastguard Worker use crate::bitwidth::BitWidth::*;
19*890232f2SAndroid Build Coastguard Worker use crate::flexbuffer_type::FlexBufferType;
20*890232f2SAndroid Build Coastguard Worker use crate::flexbuffer_type::FlexBufferType::*;
21*890232f2SAndroid Build Coastguard Worker 
22*890232f2SAndroid Build Coastguard Worker /// Internal representation of FlexBuffer Types and Data before writing.
23*890232f2SAndroid Build Coastguard Worker /// These get placed on the builder's stack and are eventually commited.
24*890232f2SAndroid Build Coastguard Worker #[derive(Debug, Clone, Copy, PartialEq)]
25*890232f2SAndroid Build Coastguard Worker pub enum Value {
26*890232f2SAndroid Build Coastguard Worker     // Inline types
27*890232f2SAndroid Build Coastguard Worker     Null,
28*890232f2SAndroid Build Coastguard Worker     Int(i64),
29*890232f2SAndroid Build Coastguard Worker     UInt(u64),
30*890232f2SAndroid Build Coastguard Worker     Float(f64),
31*890232f2SAndroid Build Coastguard Worker     Bool(bool),
32*890232f2SAndroid Build Coastguard Worker     /// Null termintated, c_string. Only used with `Map`s.
33*890232f2SAndroid Build Coastguard Worker     Key(usize),
34*890232f2SAndroid Build Coastguard Worker     /// The other ~20 or so types.
35*890232f2SAndroid Build Coastguard Worker     Reference {
36*890232f2SAndroid Build Coastguard Worker         address: usize,
37*890232f2SAndroid Build Coastguard Worker         child_width: BitWidth,
38*890232f2SAndroid Build Coastguard Worker         fxb_type: FlexBufferType,
39*890232f2SAndroid Build Coastguard Worker     },
40*890232f2SAndroid Build Coastguard Worker }
41*890232f2SAndroid Build Coastguard Worker 
42*890232f2SAndroid Build Coastguard Worker macro_rules! new_typed_vector {
43*890232f2SAndroid Build Coastguard Worker     ($name: ident, $v2: ident, $v3: ident, $v4: ident, $vn: ident) => {
44*890232f2SAndroid Build Coastguard Worker         /// Returns a typed vector, fixed length if possible.
45*890232f2SAndroid Build Coastguard Worker         /// Address and child width are zero initialized and must be set.
46*890232f2SAndroid Build Coastguard Worker         pub fn $name(n: usize) -> Value {
47*890232f2SAndroid Build Coastguard Worker             let address = 0;
48*890232f2SAndroid Build Coastguard Worker             let child_width = W8;
49*890232f2SAndroid Build Coastguard Worker             match n {
50*890232f2SAndroid Build Coastguard Worker                 2 => Value::Reference {
51*890232f2SAndroid Build Coastguard Worker                     address,
52*890232f2SAndroid Build Coastguard Worker                     child_width,
53*890232f2SAndroid Build Coastguard Worker                     fxb_type: $v2,
54*890232f2SAndroid Build Coastguard Worker                 },
55*890232f2SAndroid Build Coastguard Worker                 3 => Value::Reference {
56*890232f2SAndroid Build Coastguard Worker                     address,
57*890232f2SAndroid Build Coastguard Worker                     child_width,
58*890232f2SAndroid Build Coastguard Worker                     fxb_type: $v3,
59*890232f2SAndroid Build Coastguard Worker                 },
60*890232f2SAndroid Build Coastguard Worker                 4 => Value::Reference {
61*890232f2SAndroid Build Coastguard Worker                     address,
62*890232f2SAndroid Build Coastguard Worker                     child_width,
63*890232f2SAndroid Build Coastguard Worker                     fxb_type: $v4,
64*890232f2SAndroid Build Coastguard Worker                 },
65*890232f2SAndroid Build Coastguard Worker                 _ => Value::Reference {
66*890232f2SAndroid Build Coastguard Worker                     address,
67*890232f2SAndroid Build Coastguard Worker                     child_width,
68*890232f2SAndroid Build Coastguard Worker                     fxb_type: $vn,
69*890232f2SAndroid Build Coastguard Worker                 },
70*890232f2SAndroid Build Coastguard Worker             }
71*890232f2SAndroid Build Coastguard Worker         }
72*890232f2SAndroid Build Coastguard Worker     };
73*890232f2SAndroid Build Coastguard Worker }
74*890232f2SAndroid Build Coastguard Worker 
75*890232f2SAndroid Build Coastguard Worker impl Value {
new_vector() -> Self76*890232f2SAndroid Build Coastguard Worker     pub fn new_vector() -> Self {
77*890232f2SAndroid Build Coastguard Worker         Value::Reference {
78*890232f2SAndroid Build Coastguard Worker             address: 0,
79*890232f2SAndroid Build Coastguard Worker             child_width: W8,
80*890232f2SAndroid Build Coastguard Worker             fxb_type: Vector,
81*890232f2SAndroid Build Coastguard Worker         }
82*890232f2SAndroid Build Coastguard Worker     }
new_map() -> Self83*890232f2SAndroid Build Coastguard Worker     pub fn new_map() -> Self {
84*890232f2SAndroid Build Coastguard Worker         Value::Reference {
85*890232f2SAndroid Build Coastguard Worker             address: 0,
86*890232f2SAndroid Build Coastguard Worker             child_width: W8,
87*890232f2SAndroid Build Coastguard Worker             fxb_type: Map,
88*890232f2SAndroid Build Coastguard Worker         }
89*890232f2SAndroid Build Coastguard Worker     }
90*890232f2SAndroid Build Coastguard Worker     new_typed_vector!(
91*890232f2SAndroid Build Coastguard Worker         new_int_vector,
92*890232f2SAndroid Build Coastguard Worker         VectorInt2,
93*890232f2SAndroid Build Coastguard Worker         VectorInt3,
94*890232f2SAndroid Build Coastguard Worker         VectorInt4,
95*890232f2SAndroid Build Coastguard Worker         VectorInt
96*890232f2SAndroid Build Coastguard Worker     );
97*890232f2SAndroid Build Coastguard Worker     new_typed_vector!(
98*890232f2SAndroid Build Coastguard Worker         new_uint_vector,
99*890232f2SAndroid Build Coastguard Worker         VectorUInt2,
100*890232f2SAndroid Build Coastguard Worker         VectorUInt3,
101*890232f2SAndroid Build Coastguard Worker         VectorUInt4,
102*890232f2SAndroid Build Coastguard Worker         VectorUInt
103*890232f2SAndroid Build Coastguard Worker     );
104*890232f2SAndroid Build Coastguard Worker     new_typed_vector!(
105*890232f2SAndroid Build Coastguard Worker         new_float_vector,
106*890232f2SAndroid Build Coastguard Worker         VectorFloat2,
107*890232f2SAndroid Build Coastguard Worker         VectorFloat3,
108*890232f2SAndroid Build Coastguard Worker         VectorFloat4,
109*890232f2SAndroid Build Coastguard Worker         VectorFloat
110*890232f2SAndroid Build Coastguard Worker     );
fxb_type(&self) -> FlexBufferType111*890232f2SAndroid Build Coastguard Worker     pub fn fxb_type(&self) -> FlexBufferType {
112*890232f2SAndroid Build Coastguard Worker         match *self {
113*890232f2SAndroid Build Coastguard Worker             Value::Null => Null,
114*890232f2SAndroid Build Coastguard Worker             Value::Int(_) => Int,
115*890232f2SAndroid Build Coastguard Worker             Value::UInt(_) => UInt,
116*890232f2SAndroid Build Coastguard Worker             Value::Float(_) => Float,
117*890232f2SAndroid Build Coastguard Worker             Value::Bool(_) => Bool,
118*890232f2SAndroid Build Coastguard Worker             Value::Key(_) => Key,
119*890232f2SAndroid Build Coastguard Worker             Value::Reference { fxb_type, .. } => fxb_type,
120*890232f2SAndroid Build Coastguard Worker         }
121*890232f2SAndroid Build Coastguard Worker     }
is_fixed_length_vector(&self) -> bool122*890232f2SAndroid Build Coastguard Worker     pub fn is_fixed_length_vector(&self) -> bool {
123*890232f2SAndroid Build Coastguard Worker         self.fxb_type().is_fixed_length_vector()
124*890232f2SAndroid Build Coastguard Worker     }
is_inline(&self) -> bool125*890232f2SAndroid Build Coastguard Worker     pub fn is_inline(&self) -> bool {
126*890232f2SAndroid Build Coastguard Worker         self.fxb_type().is_inline()
127*890232f2SAndroid Build Coastguard Worker     }
is_reference(&self) -> bool128*890232f2SAndroid Build Coastguard Worker     pub fn is_reference(&self) -> bool {
129*890232f2SAndroid Build Coastguard Worker         !self.is_inline()
130*890232f2SAndroid Build Coastguard Worker     }
is_key(&self) -> bool131*890232f2SAndroid Build Coastguard Worker     pub fn is_key(&self) -> bool {
132*890232f2SAndroid Build Coastguard Worker         if let Value::Key(_) = self {
133*890232f2SAndroid Build Coastguard Worker             true
134*890232f2SAndroid Build Coastguard Worker         } else {
135*890232f2SAndroid Build Coastguard Worker             false
136*890232f2SAndroid Build Coastguard Worker         }
137*890232f2SAndroid Build Coastguard Worker     }
is_typed_vector_or_map(&self) -> bool138*890232f2SAndroid Build Coastguard Worker     pub fn is_typed_vector_or_map(&self) -> bool {
139*890232f2SAndroid Build Coastguard Worker         if let Value::Reference { fxb_type, .. } = self {
140*890232f2SAndroid Build Coastguard Worker             fxb_type.is_heterogenous()
141*890232f2SAndroid Build Coastguard Worker         } else {
142*890232f2SAndroid Build Coastguard Worker             false
143*890232f2SAndroid Build Coastguard Worker         }
144*890232f2SAndroid Build Coastguard Worker     }
prefix_length(&self) -> usize145*890232f2SAndroid Build Coastguard Worker     pub fn prefix_length(&self) -> usize {
146*890232f2SAndroid Build Coastguard Worker         if self.is_fixed_length_vector() || self.is_inline() {
147*890232f2SAndroid Build Coastguard Worker             return 0;
148*890232f2SAndroid Build Coastguard Worker         }
149*890232f2SAndroid Build Coastguard Worker         if let Value::Reference { fxb_type, .. } = self {
150*890232f2SAndroid Build Coastguard Worker             if *fxb_type == Map {
151*890232f2SAndroid Build Coastguard Worker                 return 3;
152*890232f2SAndroid Build Coastguard Worker             }
153*890232f2SAndroid Build Coastguard Worker         }
154*890232f2SAndroid Build Coastguard Worker         1
155*890232f2SAndroid Build Coastguard Worker     }
set_fxb_type_or_panic(&mut self, new_type: FlexBufferType)156*890232f2SAndroid Build Coastguard Worker     pub fn set_fxb_type_or_panic(&mut self, new_type: FlexBufferType) {
157*890232f2SAndroid Build Coastguard Worker         if let Value::Reference { fxb_type, .. } = self {
158*890232f2SAndroid Build Coastguard Worker             *fxb_type = new_type;
159*890232f2SAndroid Build Coastguard Worker         } else {
160*890232f2SAndroid Build Coastguard Worker             panic!("`set_fxb_type_or_panic` called on {:?}", self)
161*890232f2SAndroid Build Coastguard Worker         }
162*890232f2SAndroid Build Coastguard Worker     }
set_child_width_or_panic(&mut self, new_width: BitWidth)163*890232f2SAndroid Build Coastguard Worker     pub fn set_child_width_or_panic(&mut self, new_width: BitWidth) {
164*890232f2SAndroid Build Coastguard Worker         if let Value::Reference { child_width, .. } = self {
165*890232f2SAndroid Build Coastguard Worker             *child_width = new_width;
166*890232f2SAndroid Build Coastguard Worker         } else {
167*890232f2SAndroid Build Coastguard Worker             panic!("`set_child_width_or_panic` called on {:?}", self);
168*890232f2SAndroid Build Coastguard Worker         }
169*890232f2SAndroid Build Coastguard Worker     }
get_address(&self) -> Option<usize>170*890232f2SAndroid Build Coastguard Worker     pub fn get_address(&self) -> Option<usize> {
171*890232f2SAndroid Build Coastguard Worker         if let Value::Reference { address, .. } | Value::Key(address) = self {
172*890232f2SAndroid Build Coastguard Worker             Some(*address)
173*890232f2SAndroid Build Coastguard Worker         } else {
174*890232f2SAndroid Build Coastguard Worker             None
175*890232f2SAndroid Build Coastguard Worker         }
176*890232f2SAndroid Build Coastguard Worker     }
set_address_or_panic(&mut self, new_address: usize)177*890232f2SAndroid Build Coastguard Worker     pub fn set_address_or_panic(&mut self, new_address: usize) {
178*890232f2SAndroid Build Coastguard Worker         if let Value::Reference { address, .. } | Value::Key(address) = self {
179*890232f2SAndroid Build Coastguard Worker             *address = new_address;
180*890232f2SAndroid Build Coastguard Worker         } else {
181*890232f2SAndroid Build Coastguard Worker             panic!("`set_address_or_panic` called on {:?}", self);
182*890232f2SAndroid Build Coastguard Worker         }
183*890232f2SAndroid Build Coastguard Worker     }
184*890232f2SAndroid Build Coastguard Worker     /// For inline types - the width of the value to be stored.
185*890232f2SAndroid Build Coastguard Worker     /// For reference types, the width of the referred.
186*890232f2SAndroid Build Coastguard Worker     /// Note Key types always refer to 8 bit data.
width_or_child_width(&self) -> BitWidth187*890232f2SAndroid Build Coastguard Worker     pub fn width_or_child_width(&self) -> BitWidth {
188*890232f2SAndroid Build Coastguard Worker         match *self {
189*890232f2SAndroid Build Coastguard Worker             Value::Int(x) => x.into(),
190*890232f2SAndroid Build Coastguard Worker             Value::UInt(x) => x.into(),
191*890232f2SAndroid Build Coastguard Worker             Value::Float(x) => x.into(),
192*890232f2SAndroid Build Coastguard Worker             Value::Key(_) | Value::Bool(_) | Value::Null => W8,
193*890232f2SAndroid Build Coastguard Worker             Value::Reference { child_width, .. } => child_width,
194*890232f2SAndroid Build Coastguard Worker         }
195*890232f2SAndroid Build Coastguard Worker     }
relative_address(self, written_at: usize) -> Option<Value>196*890232f2SAndroid Build Coastguard Worker     pub fn relative_address(self, written_at: usize) -> Option<Value> {
197*890232f2SAndroid Build Coastguard Worker         self.get_address().map(|address| {
198*890232f2SAndroid Build Coastguard Worker             let offset = written_at
199*890232f2SAndroid Build Coastguard Worker                 .checked_sub(address)
200*890232f2SAndroid Build Coastguard Worker                 .expect("Error: References may only refer backwards in buffer.");
201*890232f2SAndroid Build Coastguard Worker             Value::UInt(offset as u64)
202*890232f2SAndroid Build Coastguard Worker         })
203*890232f2SAndroid Build Coastguard Worker     }
204*890232f2SAndroid Build Coastguard Worker     /// Computes the minimum required width of `value` when stored in a vector
205*890232f2SAndroid Build Coastguard Worker     /// starting at `vector_start` at index `idx` (this index includes the prefix).
206*890232f2SAndroid Build Coastguard Worker     /// `Value::Reference{..}` variants require location information because
207*890232f2SAndroid Build Coastguard Worker     /// offsets are relative.
width_in_vector(self, vector_start: usize, idx: usize) -> BitWidth208*890232f2SAndroid Build Coastguard Worker     pub fn width_in_vector(self, vector_start: usize, idx: usize) -> BitWidth {
209*890232f2SAndroid Build Coastguard Worker         match self {
210*890232f2SAndroid Build Coastguard Worker             Value::Bool(_) => W8,
211*890232f2SAndroid Build Coastguard Worker             Value::Null => W8,
212*890232f2SAndroid Build Coastguard Worker             Value::Int(x) => x.into(),
213*890232f2SAndroid Build Coastguard Worker             Value::UInt(x) => x.into(),
214*890232f2SAndroid Build Coastguard Worker             Value::Float(x) => x.into(),
215*890232f2SAndroid Build Coastguard Worker             _ => {
216*890232f2SAndroid Build Coastguard Worker                 debug_assert!(self.is_reference());
217*890232f2SAndroid Build Coastguard Worker                 for &width in BitWidth::iter() {
218*890232f2SAndroid Build Coastguard Worker                     let bytes = width as usize + 1;
219*890232f2SAndroid Build Coastguard Worker                     let alignment = (bytes - vector_start % bytes) % bytes;
220*890232f2SAndroid Build Coastguard Worker                     let written_at = vector_start + alignment + idx * bytes;
221*890232f2SAndroid Build Coastguard Worker                     // This match must always succeed.
222*890232f2SAndroid Build Coastguard Worker                     if let Some(Value::UInt(offset)) = self.relative_address(written_at) {
223*890232f2SAndroid Build Coastguard Worker                         if BitWidth::from(offset) == width {
224*890232f2SAndroid Build Coastguard Worker                             return width;
225*890232f2SAndroid Build Coastguard Worker                         }
226*890232f2SAndroid Build Coastguard Worker                     }
227*890232f2SAndroid Build Coastguard Worker                 }
228*890232f2SAndroid Build Coastguard Worker                 unreachable!()
229*890232f2SAndroid Build Coastguard Worker             }
230*890232f2SAndroid Build Coastguard Worker         }
231*890232f2SAndroid Build Coastguard Worker     }
packed_type(self, parent_width: BitWidth) -> u8232*890232f2SAndroid Build Coastguard Worker     pub fn packed_type(self, parent_width: BitWidth) -> u8 {
233*890232f2SAndroid Build Coastguard Worker         let width = if self.is_inline() {
234*890232f2SAndroid Build Coastguard Worker             std::cmp::max(parent_width, self.width_or_child_width())
235*890232f2SAndroid Build Coastguard Worker         } else {
236*890232f2SAndroid Build Coastguard Worker             self.width_or_child_width()
237*890232f2SAndroid Build Coastguard Worker         };
238*890232f2SAndroid Build Coastguard Worker         (self.fxb_type() as u8) << 2 | width as u8
239*890232f2SAndroid Build Coastguard Worker     }
240*890232f2SAndroid Build Coastguard Worker }
241*890232f2SAndroid Build Coastguard Worker 
find_vector_type<'a, T>(mut values: T) -> Value where T: std::iter::Iterator<Item = &'a Value>,242*890232f2SAndroid Build Coastguard Worker pub fn find_vector_type<'a, T>(mut values: T) -> Value
243*890232f2SAndroid Build Coastguard Worker where
244*890232f2SAndroid Build Coastguard Worker     T: std::iter::Iterator<Item = &'a Value>,
245*890232f2SAndroid Build Coastguard Worker {
246*890232f2SAndroid Build Coastguard Worker     let first = values.next();
247*890232f2SAndroid Build Coastguard Worker     if first.is_none() {
248*890232f2SAndroid Build Coastguard Worker         return Value::new_vector();
249*890232f2SAndroid Build Coastguard Worker     }
250*890232f2SAndroid Build Coastguard Worker     let mut len = 1;
251*890232f2SAndroid Build Coastguard Worker     let init = first.unwrap().fxb_type();
252*890232f2SAndroid Build Coastguard Worker     for v in values {
253*890232f2SAndroid Build Coastguard Worker         if v.fxb_type() != init {
254*890232f2SAndroid Build Coastguard Worker             return Value::new_vector();
255*890232f2SAndroid Build Coastguard Worker         }
256*890232f2SAndroid Build Coastguard Worker         len += 1;
257*890232f2SAndroid Build Coastguard Worker     }
258*890232f2SAndroid Build Coastguard Worker     let vector_type = match init {
259*890232f2SAndroid Build Coastguard Worker         Bool => VectorBool,
260*890232f2SAndroid Build Coastguard Worker         UInt => return Value::new_uint_vector(len),
261*890232f2SAndroid Build Coastguard Worker         Int => return Value::new_int_vector(len),
262*890232f2SAndroid Build Coastguard Worker         Float => return Value::new_float_vector(len),
263*890232f2SAndroid Build Coastguard Worker         Key => VectorKey,
264*890232f2SAndroid Build Coastguard Worker         // Note that VectorString is deprecated for writing
265*890232f2SAndroid Build Coastguard Worker         _ => return Value::new_vector(),
266*890232f2SAndroid Build Coastguard Worker     };
267*890232f2SAndroid Build Coastguard Worker     Value::Reference {
268*890232f2SAndroid Build Coastguard Worker         address: 0,
269*890232f2SAndroid Build Coastguard Worker         child_width: W8,
270*890232f2SAndroid Build Coastguard Worker         fxb_type: vector_type,
271*890232f2SAndroid Build Coastguard Worker     }
272*890232f2SAndroid Build Coastguard Worker }
273*890232f2SAndroid Build Coastguard Worker 
274*890232f2SAndroid Build Coastguard Worker #[inline]
store_value(buffer: &mut Vec<u8>, mut value: Value, width: BitWidth)275*890232f2SAndroid Build Coastguard Worker pub fn store_value(buffer: &mut Vec<u8>, mut value: Value, width: BitWidth) {
276*890232f2SAndroid Build Coastguard Worker     // Remap to number types.
277*890232f2SAndroid Build Coastguard Worker     use Value::*;
278*890232f2SAndroid Build Coastguard Worker     if let Some(offset) = value.relative_address(buffer.len()) {
279*890232f2SAndroid Build Coastguard Worker         value = offset;
280*890232f2SAndroid Build Coastguard Worker     } else {
281*890232f2SAndroid Build Coastguard Worker         value = match value {
282*890232f2SAndroid Build Coastguard Worker             Bool(x) => UInt(x.into()),
283*890232f2SAndroid Build Coastguard Worker             Null => UInt(0), // Should this be 0 bytes?
284*890232f2SAndroid Build Coastguard Worker             _ => value,
285*890232f2SAndroid Build Coastguard Worker         }
286*890232f2SAndroid Build Coastguard Worker     }
287*890232f2SAndroid Build Coastguard Worker     let write_result = match (value, width) {
288*890232f2SAndroid Build Coastguard Worker         (UInt(x), W8) => buffer.write_u8(x as u8),
289*890232f2SAndroid Build Coastguard Worker         (UInt(x), W16) => buffer.write_u16::<LittleEndian>(x as u16),
290*890232f2SAndroid Build Coastguard Worker         (UInt(x), W32) => buffer.write_u32::<LittleEndian>(x as u32),
291*890232f2SAndroid Build Coastguard Worker         (UInt(x), W64) => buffer.write_u64::<LittleEndian>(x),
292*890232f2SAndroid Build Coastguard Worker         (Int(x), W8) => buffer.write_i8(x as i8),
293*890232f2SAndroid Build Coastguard Worker         (Int(x), W16) => buffer.write_i16::<LittleEndian>(x as i16),
294*890232f2SAndroid Build Coastguard Worker         (Int(x), W32) => buffer.write_i32::<LittleEndian>(x as i32),
295*890232f2SAndroid Build Coastguard Worker         (Int(x), W64) => buffer.write_i64::<LittleEndian>(x),
296*890232f2SAndroid Build Coastguard Worker         (Float(x), W32) => buffer.write_f32::<LittleEndian>(x as f32),
297*890232f2SAndroid Build Coastguard Worker         (Float(x), W64) => buffer.write_f64::<LittleEndian>(x),
298*890232f2SAndroid Build Coastguard Worker         (Float(_), _) => unreachable!("Error: Flatbuffers does not support 8 and 16 bit floats."),
299*890232f2SAndroid Build Coastguard Worker         _ => unreachable!("Variant not considered: {:?}", value),
300*890232f2SAndroid Build Coastguard Worker     };
301*890232f2SAndroid Build Coastguard Worker     write_result.unwrap_or_else(|err| {
302*890232f2SAndroid Build Coastguard Worker         panic!(
303*890232f2SAndroid Build Coastguard Worker             "Error writing value {:?} with width {:?}: {:?}",
304*890232f2SAndroid Build Coastguard Worker             value, width, err
305*890232f2SAndroid Build Coastguard Worker         )
306*890232f2SAndroid Build Coastguard Worker     });
307*890232f2SAndroid Build Coastguard Worker }
308