xref: /aosp_15_r20/external/flatbuffers/tests/rust_usage_test/tests/integration_test.rs (revision 890232f25432b36107d06881e0a25aaa6b473652)
1 /*
2  *
3  * Copyright 2018 Google Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #![no_std]
19 
20 #[cfg(not(feature = "no_std"))]
21 extern crate std;
22 #[cfg(not(feature = "no_std"))]
23 use alloc::vec::Vec;
24 
25 #[macro_use]
26 extern crate alloc;
27 
28 use alloc::string::String;
29 
30 #[cfg(feature = "no_std")]
31 #[global_allocator]
32 static ALLOCATOR: libc_alloc::LibcAlloc = libc_alloc::LibcAlloc;
33 
34 #[macro_use]
35 #[cfg(not(miri))] // slow.
36 extern crate quickcheck;
37 extern crate flatbuffers;
38 extern crate flexbuffers;
39 extern crate rand;
40 extern crate serde;
41 #[macro_use]
42 extern crate serde_derive;
43 #[cfg(not(miri))] // slow.
44 #[macro_use]
45 extern crate quickcheck_derive;
46 
47 mod flexbuffers_tests;
48 mod more_defaults_test;
49 mod optional_scalars_test;
50 
51 #[allow(dead_code, unused_imports)]
52 #[path = "../../include_test1/mod.rs"]
53 pub mod include_test1_generated;
54 
55 #[allow(dead_code, unused_imports)]
56 #[path = "../../include_test2/mod.rs"]
57 pub mod include_test2_generated;
58 
59 #[allow(dead_code, unused_imports)]
60 #[path = "../../namespace_test/mod.rs"]
61 pub mod namespace_test_generated;
62 
63 #[allow(dead_code, unused_imports)]
64 #[path = "../../monster_test/mod.rs"]
65 mod monster_test_generated;
66 pub use monster_test_generated::my_game;
67 
68 #[allow(dead_code, unused_imports)]
69 #[path = "../../optional_scalars/mod.rs"]
70 mod optional_scalars_generated;
71 
72 #[allow(dead_code, unused_imports)]
73 #[path = "../../arrays_test/mod.rs"]
74 mod arrays_test_generated;
75 
76 // We use incorrect casing to test keywords.
77 #[allow(dead_code, unused_imports, non_camel_case_types, non_snake_case)]
78 #[path = "../../keyword_test/mod.rs"]
79 mod keyword_test_generated;
80 
81 #[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
82 #[allow(dead_code)]
83 mod flatbuffers_tests {
84 use super::*;
85 
86 // Include simple random number generator to ensure results will be the
87 // same across platforms.
88 // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
89 struct LCG(u64);
90 impl LCG {
new() -> Self91     fn new() -> Self {
92         LCG { 0: 48271 }
93     }
next(&mut self) -> u6494     fn next(&mut self) -> u64 {
95         let old = self.0;
96         self.0 = (self.0 * 279470273u64) % 4294967291u64;
97         old
98     }
reset(&mut self)99     fn reset(&mut self) {
100         self.0 = 48271
101     }
102 }
103 
104 // test helper macro to return an error if two expressions are not equal
105 macro_rules! check_eq {
106     ($field_call:expr, $want:expr) => (
107         if $field_call == $want {
108             Ok(())
109         } else {
110             Err(stringify!($field_call))
111         }
112     )
113 }
114 
115 #[test]
macro_check_eq()116 fn macro_check_eq() {
117     assert!(check_eq!(1, 1).is_ok());
118     assert!(check_eq!(1, 2).is_err());
119 }
120 
121 // test helper macro to return an error if two expressions are equal
122 macro_rules! check_is_some {
123     ($field_call:expr) => (
124         if $field_call.is_some() {
125             Ok(())
126         } else {
127             Err(stringify!($field_call))
128         }
129     )
130 }
131 
132 #[test]
macro_check_is_some()133 fn macro_check_is_some() {
134     let some: Option<usize> = Some(0);
135     let none: Option<usize> = None;
136     assert!(check_is_some!(some).is_ok());
137     assert!(check_is_some!(none).is_err());
138 }
139 
140 #[test]
object_api_defaults()141 fn object_api_defaults() {
142     use my_game::example::*;
143     assert_eq!(
144         Vec3T::default(), Vec3T {
145         x: 0.0,
146         y: 0.0,
147         z: 0.0,
148         test1: 0.0,
149         test2: Color::empty(),
150         test3: TestT {
151             a: 0,
152             b: 0
153         }
154     });
155     assert_eq!(
156         MonsterT::default(),
157         MonsterT {
158             pos: None,
159             hp: 100,
160             mana: 150,
161             name: String::new(),  // required string => default is empty string.
162             color: Color::Blue,
163             inventory: None,
164             testarrayoftables: None,
165             testarrayofstring: None,
166             testarrayofstring2: None,
167             testarrayofbools: None,
168             testarrayofsortedstruct: None,
169             enemy: None,
170             test: AnyT::NONE,
171             test4: None,
172             test5: None,
173             testnestedflatbuffer: None,
174             testempty: None,
175             testbool: false,
176             testhashs32_fnv1: 0,
177             testhashu32_fnv1: 0,
178             testhashs64_fnv1: 0,
179             testhashu64_fnv1: 0,
180             testhashs32_fnv1a: 0,
181             testhashu32_fnv1a: 0,
182             testhashs64_fnv1a: 0,
183             testhashu64_fnv1a: 0,
184             testf: 3.14159,
185             testf2: 3.0,
186             testf3: 0.0,
187             flex: None,
188             vector_of_longs: None,
189             vector_of_doubles: None,
190             parent_namespace_test: None,
191             vector_of_referrables: None,
192             single_weak_reference: 0,
193             vector_of_weak_references: None,
194             vector_of_strong_referrables: None,
195             co_owning_reference: 0,
196             vector_of_co_owning_references: None,
197             non_owning_reference: 0,
198             vector_of_non_owning_references: None,
199             any_unique: AnyUniqueAliasesT::NONE,
200             any_ambiguous: AnyAmbiguousAliasesT::NONE,
201             vector_of_enums: None,
202             signed_enum: Race::None,
203             testrequirednestedflatbuffer: None,  // despite the name, it is not required.
204             scalar_key_sorted_tables: None,
205             native_inline: None,
206             long_enum_non_enum_default: Default::default(),
207             long_enum_normal_default: LongEnum::LongOne,
208         }
209     );
210 }
211 
create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder)212 fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
213     let mon = {
214         let s0 = builder.create_string("test1");
215         let s1 = builder.create_string("test2");
216         let fred_name = builder.create_string("Fred");
217 
218         // can't inline creation of this Vec3 because we refer to it by reference, so it must live
219         // long enough to be used by MonsterArgs.
220         let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
221 
222         let args = my_game::example::MonsterArgs{
223             hp: 80,
224             mana: 150,
225             name: Some(builder.create_string("MyMonster")),
226             pos: Some(&pos),
227             test_type: my_game::example::Any::Monster,
228             test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
229                 name: Some(fred_name),
230                 ..Default::default()
231             }).as_union_value()),
232             inventory: Some(builder.create_vector_direct(&[0u8, 1, 2, 3, 4][..])),
233             test4: Some(builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
234                                                        my_game::example::Test::new(30, 40)])),
235             testarrayofstring: Some(builder.create_vector(&[s0, s1])),
236             ..Default::default()
237         };
238         my_game::example::Monster::create(builder, &args)
239     };
240     my_game::example::finish_monster_buffer(builder, mon);
241 }
242 
create_serialized_example_with_library_code(builder: &mut flatbuffers::FlatBufferBuilder)243 fn create_serialized_example_with_library_code(builder: &mut flatbuffers::FlatBufferBuilder) {
244     let nested_union_mon = {
245         let name = builder.create_string("Fred");
246         let table_start = builder.start_table();
247         builder.push_slot_always(my_game::example::Monster::VT_NAME, name);
248         builder.end_table(table_start)
249     };
250     let pos = my_game::example::Vec3::new(1.0, 2.0, 3.0, 3.0, my_game::example::Color::Green, &my_game::example::Test::new(5i16, 6i8));
251     let inv = builder.create_vector(&[0u8, 1, 2, 3, 4]);
252 
253     let test4 = builder.create_vector(&[my_game::example::Test::new(10, 20),
254                                         my_game::example::Test::new(30, 40)][..]);
255 
256     let name = builder.create_string("MyMonster");
257     let testarrayofstring = builder.create_vector_of_strings(&["test1", "test2"][..]);
258 
259     // begin building
260 
261     let table_start = builder.start_table();
262     builder.push_slot(my_game::example::Monster::VT_HP, 80i16, 100);
263     builder.push_slot_always(my_game::example::Monster::VT_NAME, name);
264     builder.push_slot_always(my_game::example::Monster::VT_POS, &pos);
265     builder.push_slot(my_game::example::Monster::VT_TEST_TYPE, my_game::example::Any::Monster, my_game::example::Any::NONE);
266     builder.push_slot_always(my_game::example::Monster::VT_TEST, nested_union_mon);
267     builder.push_slot_always(my_game::example::Monster::VT_INVENTORY, inv);
268     builder.push_slot_always(my_game::example::Monster::VT_TEST4, test4);
269     builder.push_slot_always(my_game::example::Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
270     let root = builder.end_table(table_start);
271     builder.finish(root, Some(my_game::example::MONSTER_IDENTIFIER));
272 }
273 
serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_required: bool, size_prefixed: bool) -> Result<(), &'static str>274 fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_required: bool, size_prefixed: bool) -> Result<(), &'static str> {
275 
276     if identifier_required {
277         let correct = if size_prefixed {
278             my_game::example::monster_size_prefixed_buffer_has_identifier(bytes)
279         } else {
280             my_game::example::monster_buffer_has_identifier(bytes)
281         };
282         check_eq!(correct, true)?;
283     }
284 
285     let m = if size_prefixed {
286         my_game::example::size_prefixed_root_as_monster(bytes).unwrap()
287     } else {
288         my_game::example::root_as_monster(bytes).unwrap()
289     };
290 
291     check_eq!(m.hp(), 80)?;
292     check_eq!(m.mana(), 150)?;
293     check_eq!(m.name(), "MyMonster")?;
294 
295     let pos = m.pos().unwrap();
296     check_eq!(pos.x(), 1.0f32)?;
297     check_eq!(pos.y(), 2.0f32)?;
298     check_eq!(pos.z(), 3.0f32)?;
299     check_eq!(pos.test1(), 3.0f64)?;
300     check_eq!(pos.test2(), my_game::example::Color::Green)?;
301 
302     let pos_test3 = pos.test3();
303     check_eq!(pos_test3.a(), 5i16)?;
304     check_eq!(pos_test3.b(), 6i8)?;
305 
306     check_eq!(m.test_type(), my_game::example::Any::Monster)?;
307     check_is_some!(m.test())?;
308     let table2 = m.test().unwrap();
309     let monster2 = my_game::example::Monster::init_from_table(table2);
310 
311     check_eq!(monster2.name(), "Fred")?;
312 
313     check_is_some!(m.inventory())?;
314     let inv = m.inventory().unwrap();
315     check_eq!(inv.len(), 5)?;
316     check_eq!(inv.iter().sum::<u8>(), 10u8)?;
317     check_eq!(inv.iter().rev().sum::<u8>(), 10u8)?;
318 
319     check_is_some!(m.test4())?;
320     let test4 = m.test4().unwrap();
321     check_eq!(test4.len(), 2)?;
322     check_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
323               test4[1].a() as i32 + test4[1].b() as i32, 100)?;
324 
325     check_is_some!(m.testarrayofstring())?;
326     let testarrayofstring = m.testarrayofstring().unwrap();
327     check_eq!(testarrayofstring.len(), 2)?;
328     check_eq!(testarrayofstring.get(0), "test1")?;
329     check_eq!(testarrayofstring.get(1), "test2")?;
330 
331     Ok(())
332 }
333 
334 #[test]
test_object_api_reads_correctly() -> Result<(), &'static str>335 fn test_object_api_reads_correctly() -> Result<(), &'static str>{
336     let mut fbb = flatbuffers::FlatBufferBuilder::new();
337     create_serialized_example_with_library_code(&mut fbb);
338 
339     let m = my_game::example::root_as_monster(fbb.finished_data()).unwrap().unpack();
340 
341     check_eq!(m.hp, 80)?;
342     check_eq!(m.mana, 150)?;
343     check_eq!(m.name, "MyMonster")?;
344 
345     let pos = m.pos.as_ref().unwrap();
346     check_eq!(pos.x, 1.0f32)?;
347     check_eq!(pos.y, 2.0f32)?;
348     check_eq!(pos.z, 3.0f32)?;
349     check_eq!(pos.test1, 3.0f64)?;
350     check_eq!(pos.test2, my_game::example::Color::Green)?;
351 
352     let pos_test3 = &pos.test3;
353     check_eq!(pos_test3.a, 5i16)?;
354     check_eq!(pos_test3.b, 6i8)?;
355 
356     let monster2 = m.test.as_monster().unwrap();
357     check_eq!(monster2.name, "Fred")?;
358 
359     let inv = m.inventory.as_ref().unwrap();
360     check_eq!(inv.len(), 5)?;
361     check_eq!(inv.iter().sum::<u8>(), 10u8)?;
362     check_eq!(inv.iter().rev().sum::<u8>(), 10u8)?;
363 
364     let test4 = m.test4.as_ref().unwrap();
365     check_eq!(test4.len(), 2)?;
366     check_eq!(test4[0].a as i32 + test4[0].b as i32 +
367               test4[1].a as i32 + test4[1].b as i32, 100)?;
368 
369     let testarrayofstring = m.testarrayofstring.as_ref().unwrap();
370     check_eq!(testarrayofstring.len(), 2)?;
371     check_eq!(testarrayofstring[0], "test1")?;
372     check_eq!(testarrayofstring[1], "test2")?;
373     Ok(())
374 }
375 
376 
377 
378 // Disabled due to Windows CI limitations.
379 // #[test]
380 // fn builder_initializes_with_maximum_buffer_size() {
381 //     flatbuffers::FlatBufferBuilder::with_capacity(flatbuffers::FLATBUFFERS_MAX_BUFFER_SIZE);
382 // }
383 
384 #[should_panic]
385 #[test]
builder_abort_with_greater_than_maximum_buffer_size()386 fn builder_abort_with_greater_than_maximum_buffer_size() {
387     flatbuffers::FlatBufferBuilder::with_capacity(flatbuffers::FLATBUFFERS_MAX_BUFFER_SIZE+1);
388 }
389 
390 #[test]
builder_collapses_into_vec()391 fn builder_collapses_into_vec() {
392     let mut b = flatbuffers::FlatBufferBuilder::new();
393     create_serialized_example_with_generated_code(&mut b);
394     let (backing_buf, head) = b.collapse();
395     serialized_example_is_accessible_and_correct(&backing_buf[head..], true, false).unwrap();
396 }
397 
398 #[test]
399 #[cfg(not(miri))]  // slow.
verifier_one_byte_errors_do_not_crash()400 fn verifier_one_byte_errors_do_not_crash() {
401     let mut b = flatbuffers::FlatBufferBuilder::new();
402     create_serialized_example_with_library_code(&mut b);
403     let mut badbuf = b.finished_data().to_vec();
404     // If the verifier says a buffer is okay then using it won't cause a crash.
405     // We use write_fmt since Debug visits all the fields - but there's no need to store anything.
406     struct ForgetfulWriter;
407     use core::fmt::Write;
408     impl Write for ForgetfulWriter {
409         fn write_str(&mut self, _: &str) -> Result<(), core::fmt::Error> {
410             Ok(())
411         }
412     }
413     let mut w = ForgetfulWriter;
414     for d in 1..=255u8 {
415         for i in 0..badbuf.len() {
416             let orig = badbuf[i];
417             badbuf[i] = badbuf[i].wrapping_add(d);
418             if let Ok(m) = flatbuffers::root::<my_game::example::Monster>(&badbuf) {
419                 w.write_fmt(format_args!("{:?}", m)).unwrap()
420             }
421             badbuf[i] = orig;
422         }
423     }
424 }
425 #[test]
426 #[cfg(not(miri))]  // slow.
verifier_too_many_tables()427 fn verifier_too_many_tables() {
428     use my_game::example::*;
429     let b = &mut flatbuffers::FlatBufferBuilder::new();
430     let r = Referrable::create(b, &ReferrableArgs { id: 42 });
431     let rs = b.create_vector(&vec![r; 500]);
432     let name = Some(b.create_string("foo"));
433     let m = Monster::create(b, &MonsterArgs {
434         vector_of_referrables: Some(rs),
435         name,  // required field.
436         ..Default::default()
437     });
438     b.finish(m, None);
439 
440     let data = b.finished_data();
441     let mut opts = flatbuffers::VerifierOptions::default();
442 
443     opts.max_tables = 500;
444     let res = flatbuffers::root_with_opts::<Monster>(&opts, data);
445     assert_eq!(res.unwrap_err(), flatbuffers::InvalidFlatbuffer::TooManyTables);
446 
447     opts.max_tables += 2;
448     assert!(flatbuffers::root_with_opts::<Monster>(&opts, data).is_ok());
449 }
450 #[test]
451 #[cfg(not(miri))]  // slow.
verifier_apparent_size_too_large()452 fn verifier_apparent_size_too_large() {
453     use my_game::example::*;
454     let b = &mut flatbuffers::FlatBufferBuilder::new();
455     let name = Some(b.create_string("foo"));
456     // String amplification attack.
457     let s = b.create_string(&(core::iter::repeat("X").take(1000).collect::<String>()));
458     let testarrayofstring = Some(b.create_vector(&vec![s; 1000]));
459     let m = Monster::create(b, &MonsterArgs {
460         testarrayofstring,
461         name,  // required field.
462         ..Default::default()
463     });
464     b.finish(m, None);
465     let data = b.finished_data();
466     assert!(data.len() < 5100);  // est 4000 for the vector + 1000 for the string + 100 overhead.
467     let mut opts = flatbuffers::VerifierOptions::default();
468     opts.max_apparent_size = 1_000_000;
469 
470     let res = flatbuffers::root_with_opts::<Monster>(&opts, data);
471     assert_eq!(res.unwrap_err(), flatbuffers::InvalidFlatbuffer::ApparentSizeTooLarge);
472 
473     opts.max_apparent_size += 20_000;
474     assert!(flatbuffers::root_with_opts::<Monster>(&opts, data).is_ok());
475 }
476 #[test]
verifier_in_too_deep()477 fn verifier_in_too_deep() {
478     use my_game::example::*;
479     let b = &mut flatbuffers::FlatBufferBuilder::new();
480     let name = Some(b.create_string("foo"));
481     let mut prev_monster = None;
482     for _ in 0..11 {
483         prev_monster = Some(Monster::create(b, &MonsterArgs {
484             enemy: prev_monster,
485             name,  // required field.
486             ..Default::default()
487         }));
488     };
489     b.finish(prev_monster.unwrap(), None);
490     let mut opts = flatbuffers::VerifierOptions::default();
491     opts.max_depth = 10;
492 
493     let data = b.finished_data();
494     let res = flatbuffers::root_with_opts::<Monster>(&opts, data);
495     assert_eq!(res.unwrap_err(), flatbuffers::InvalidFlatbuffer::DepthLimitReached);
496 
497     opts.max_depth += 1;
498     assert!(flatbuffers::root_with_opts::<Monster>(&opts, data).is_ok());
499 }
500 
501 #[cfg(test)]
502 mod generated_constants {
503     extern crate flatbuffers;
504     use super::my_game;
505 
506     #[test]
monster_identifier()507     fn monster_identifier() {
508         assert_eq!("MONS", my_game::example::MONSTER_IDENTIFIER);
509     }
510 
511     #[test]
monster_file_extension()512     fn monster_file_extension() {
513         assert_eq!("mon", my_game::example::MONSTER_EXTENSION);
514     }
515 
516     #[test]
enum_constants_are_public()517     fn enum_constants_are_public() {
518         assert_eq!(-1, my_game::example::Race::ENUM_MIN);
519         assert_eq!(2, my_game::example::Race::ENUM_MAX);
520         assert_eq!(my_game::example::Race::ENUM_VALUES, [
521             my_game::example::Race::None,
522             my_game::example::Race::Human,
523             my_game::example::Race::Dwarf,
524             my_game::example::Race::Elf,
525         ]);
526 
527         assert_eq!(0, my_game::example::Any::ENUM_MIN);
528         assert_eq!(3, my_game::example::Any::ENUM_MAX);
529         assert_eq!(my_game::example::Any::ENUM_VALUES, [
530             my_game::example::Any::NONE,
531             my_game::example::Any::Monster,
532             my_game::example::Any::TestSimpleTableWithEnum,
533             my_game::example::Any::MyGame_Example2_Monster,
534         ]);
535 
536         assert_eq!(0, my_game::example::AnyUniqueAliases::ENUM_MIN);
537         assert_eq!(3, my_game::example::AnyUniqueAliases::ENUM_MAX);
538         assert_eq!(my_game::example::AnyUniqueAliases::ENUM_VALUES, [
539             my_game::example::AnyUniqueAliases::NONE,
540             my_game::example::AnyUniqueAliases::M,
541             my_game::example::AnyUniqueAliases::TS,
542             my_game::example::AnyUniqueAliases::M2,
543         ]);
544 
545         assert_eq!(0, my_game::example::AnyAmbiguousAliases::ENUM_MIN);
546         assert_eq!(3, my_game::example::AnyAmbiguousAliases::ENUM_MAX);
547         assert_eq!(my_game::example::AnyAmbiguousAliases::ENUM_VALUES, [
548             my_game::example::AnyAmbiguousAliases::NONE,
549             my_game::example::AnyAmbiguousAliases::M1,
550             my_game::example::AnyAmbiguousAliases::M2,
551             my_game::example::AnyAmbiguousAliases::M3,
552         ]);
553     }
554 }
555 
556 #[cfg(not(feature = "no_std"))]
557 #[cfg(test)]
558 mod lifetime_correctness {
559     extern crate flatbuffers;
560 
561     use core::mem;
562 
563     use super::my_game;
564     use super::load_file;
565 
566     #[test]
table_get_field_from_static_buffer_1()567     fn table_get_field_from_static_buffer_1() {
568         let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
569         // create 'static slice
570         let slice: &[u8] = &buf;
571         let slice: &'static [u8] = unsafe { mem::transmute(slice) };
572         // make sure values retrieved from the 'static buffer are themselves 'static
573         let monster: my_game::example::Monster<'static> = my_game::example::root_as_monster(slice).unwrap();
574         // this line should compile:
575         let name: Option<&'static str> = monster._tab.get::<flatbuffers::ForwardsUOffset<&str>>(my_game::example::Monster::VT_NAME, None);
576         assert_eq!(name, Some("MyMonster"));
577     }
578 
579     #[test]
table_get_field_from_static_buffer_2()580     fn table_get_field_from_static_buffer_2() {
581         static DATA: [u8; 4] = [0, 0, 0, 0]; // some binary data
582         let table: flatbuffers::Table<'static> = flatbuffers::Table::new(&DATA, 0);
583         // this line should compile:
584         table.get::<&'static str>(0, None);
585     }
586 
587     #[test]
table_object_self_lifetime_in_closure()588     fn table_object_self_lifetime_in_closure() {
589         // This test is designed to ensure that lifetimes for temporary intermediate tables aren't inflated beyond where the need to be.
590         let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
591         let monster = my_game::example::root_as_monster(&buf).unwrap();
592         let enemy: Option<my_game::example::Monster> = monster.enemy();
593         // This line won't compile if "self" is required to live for the lifetime of buf above as the borrow disappears at the end of the closure.
594         let enemy_of_my_enemy = enemy.map(|e| {
595             // enemy (the Option) is consumed, and the enum's value is taken as a temporary (e) at the start of the closure
596             let name = e.name();
597             // ... the temporary dies here, so for this to compile name's lifetime must not be tied to the temporary
598             name
599             // If this test fails the error would be "`e` dropped here while still borrowed"
600         });
601         assert_eq!(enemy_of_my_enemy, Some("Fred"));
602     }
603 }
604 
605 #[cfg(test)]
606 mod roundtrip_generated_code {
607     extern crate flatbuffers;
608 
609     use alloc::vec::Vec;
610 
611     use super::my_game;
612 
build_mon<'a, 'b>(builder: &'a mut flatbuffers::FlatBufferBuilder, args: &'b my_game::example::MonsterArgs) -> my_game::example::Monster<'a>613     fn build_mon<'a, 'b>(builder: &'a mut flatbuffers::FlatBufferBuilder, args: &'b my_game::example::MonsterArgs) -> my_game::example::Monster<'a> {
614         let mon = my_game::example::Monster::create(builder, &args);
615         my_game::example::finish_monster_buffer(builder, mon);
616         my_game::example::root_as_monster(builder.finished_data()).unwrap()
617     }
618 
619     #[test]
scalar_store()620     fn scalar_store() {
621         let mut b = flatbuffers::FlatBufferBuilder::new();
622         let name = b.create_string("foo");
623         let m = build_mon(&mut b, &my_game::example::MonsterArgs{hp: 123, name: Some(name), ..Default::default()});
624         assert_eq!(m.hp(), 123);
625     }
626     #[test]
scalar_default()627     fn scalar_default() {
628         let mut b = flatbuffers::FlatBufferBuilder::new();
629         let name = b.create_string("foo");
630         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
631         assert_eq!(m.hp(), 100);
632     }
633     #[test]
string_store()634     fn string_store() {
635         let mut b = flatbuffers::FlatBufferBuilder::new();
636         let name = b.create_string("foobar");
637         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
638         assert_eq!(m.name(), "foobar");
639     }
640     #[test]
struct_store()641     fn struct_store() {
642         let mut b = flatbuffers::FlatBufferBuilder::new();
643         let name = b.create_string("foo");
644         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
645             name: Some(name),
646             pos: Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
647                                                    my_game::example::Color::Green,
648                                                    &my_game::example::Test::new(98, 99))),
649             ..Default::default()
650         });
651         assert_eq!(m.pos(), Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
652                                                               my_game::example::Color::Green,
653                                                               &my_game::example::Test::new(98, 99))));
654     }
655     #[test]
struct_default()656     fn struct_default() {
657         let mut b = flatbuffers::FlatBufferBuilder::new();
658         let name = b.create_string("foo");
659         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
660         assert_eq!(m.pos(), None);
661     }
662     #[test]
enum_store()663     fn enum_store() {
664         let mut b = flatbuffers::FlatBufferBuilder::new();
665         let name = b.create_string("foo");
666         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), color: my_game::example::Color::Red, ..Default::default()});
667         assert_eq!(m.color(), my_game::example::Color::Red);
668     }
669     #[test]
enum_default()670     fn enum_default() {
671         let mut b = flatbuffers::FlatBufferBuilder::new();
672         let name = b.create_string("foo");
673         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
674         assert_eq!(m.color(), my_game::example::Color::Blue);
675     }
676     #[test]
union_store()677     fn union_store() {
678         let b = &mut flatbuffers::FlatBufferBuilder::new();
679         {
680             let name_inner = b.create_string("foo");
681             let name_outer = b.create_string("bar");
682 
683             let inner = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
684                 name: Some(name_inner),
685                 ..Default::default()
686             });
687             let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
688                 name: Some(name_outer),
689                 test_type: my_game::example::Any::Monster,
690                 test: Some(inner.as_union_value()),
691                 ..Default::default()
692             });
693             my_game::example::finish_monster_buffer(b, outer);
694         }
695 
696         let mon = my_game::example::root_as_monster(b.finished_data()).unwrap();
697         assert_eq!(mon.name(), "bar");
698         assert_eq!(mon.test_type(), my_game::example::Any::Monster);
699         assert_eq!(my_game::example::Monster::init_from_table(mon.test().unwrap()).name(),
700                    "foo");
701         assert_eq!(mon.test_as_monster().unwrap().name(), "foo");
702         assert_eq!(mon.test_as_test_simple_table_with_enum(), None);
703         assert_eq!(mon.test_as_my_game_example_2_monster(), None);
704     }
705     #[test]
union_default()706     fn union_default() {
707         let mut b = flatbuffers::FlatBufferBuilder::new();
708         let name = b.create_string("foo");
709         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
710         assert_eq!(m.test_type(), my_game::example::Any::NONE);
711         assert_eq!(m.test(), None);
712     }
713     #[test]
table_full_namespace_store()714     fn table_full_namespace_store() {
715         let b = &mut flatbuffers::FlatBufferBuilder::new();
716         {
717             let name_inner = b.create_string("foo");
718             let name_outer = b.create_string("bar");
719 
720             let inner = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
721                 name: Some(name_inner),
722                 ..Default::default()
723             });
724             let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
725                 name: Some(name_outer),
726                 enemy: Some(inner),
727                 ..Default::default()
728             });
729             my_game::example::finish_monster_buffer(b, outer);
730         }
731 
732         let mon = my_game::example::root_as_monster(b.finished_data()).unwrap();
733         assert_eq!(mon.name(), "bar");
734         assert_eq!(mon.enemy().unwrap().name(), "foo");
735     }
736     #[test]
table_full_namespace_default()737     fn table_full_namespace_default() {
738         let mut b = flatbuffers::FlatBufferBuilder::new();
739         let name = b.create_string("foo");
740         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
741         assert_eq!(m.enemy(), None);
742     }
743     #[test]
table_store()744     fn table_store() {
745         let b = &mut flatbuffers::FlatBufferBuilder::new();
746         {
747             let id_inner = b.create_string("foo");
748             let name_outer = b.create_string("bar");
749 
750             let inner = my_game::example::Stat::create(b, &my_game::example::StatArgs{
751                 id: Some(id_inner),
752                 ..Default::default()
753             });
754             let outer = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
755                 name: Some(name_outer),
756                 testempty: Some(inner),
757                 ..Default::default()
758             });
759             my_game::example::finish_monster_buffer(b, outer);
760         }
761 
762         let mon = my_game::example::root_as_monster(b.finished_data()).unwrap();
763         assert_eq!(mon.name(), "bar");
764         assert_eq!(mon.testempty().unwrap().id(), Some("foo"));
765     }
766     #[test]
table_default()767     fn table_default() {
768         let mut b = flatbuffers::FlatBufferBuilder::new();
769         let name = b.create_string("foo");
770         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
771         assert_eq!(m.testempty(), None);
772     }
773     #[test]
nested_flatbuffer_store()774     fn nested_flatbuffer_store() {
775         let b0 = {
776             let mut b0 = flatbuffers::FlatBufferBuilder::new();
777             let args = my_game::example::MonsterArgs{
778                 hp: 123,
779                 name: Some(b0.create_string("foobar")),
780                 ..Default::default()
781             };
782             let mon = my_game::example::Monster::create(&mut b0, &args);
783             my_game::example::finish_monster_buffer(&mut b0, mon);
784             b0
785         };
786 
787         let b1 = {
788             let mut b1 = flatbuffers::FlatBufferBuilder::new();
789             let args = my_game::example::MonsterArgs{
790                 testnestedflatbuffer: Some(b1.create_vector(b0.finished_data())),
791                 name: Some(b1.create_string("foo")),
792                 ..Default::default()
793             };
794             let mon = my_game::example::Monster::create(&mut b1, &args);
795             my_game::example::finish_monster_buffer(&mut b1, mon);
796             b1
797         };
798 
799         let m = my_game::example::root_as_monster(b1.finished_data()).unwrap();
800 
801         assert!(m.testnestedflatbuffer().is_some());
802         assert_eq!(m.testnestedflatbuffer().unwrap(), b0.finished_data());
803 
804         let m2_a = my_game::example::root_as_monster(m.testnestedflatbuffer().unwrap()).unwrap();
805         assert_eq!(m2_a.hp(), 123);
806         assert_eq!(m2_a.name(), "foobar");
807 
808         assert!(m.testnestedflatbuffer_nested_flatbuffer().is_some());
809         let m2_b = m.testnestedflatbuffer_nested_flatbuffer().unwrap();
810 
811         assert_eq!(m2_b.hp(), 123);
812         assert_eq!(m2_b.name(), "foobar");
813     }
814     #[test]
nested_flatbuffer_default()815     fn nested_flatbuffer_default() {
816         let mut b = flatbuffers::FlatBufferBuilder::new();
817         let name = b.create_string("foo");
818         let m = build_mon(&mut b, &my_game::example::MonsterArgs{name: Some(name), ..Default::default()});
819         assert!(m.testnestedflatbuffer().is_none());
820     }
821     #[test]
vector_of_string_store_helper_build()822     fn vector_of_string_store_helper_build() {
823         let mut b = flatbuffers::FlatBufferBuilder::new();
824         let v = b.create_vector_of_strings(&["foobar", "baz"]);
825         let name = b.create_string("foo");
826         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
827             name: Some(name),
828             testarrayofstring: Some(v), ..Default::default()});
829         assert_eq!(m.testarrayofstring().unwrap().len(), 2);
830         assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
831         assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
832 
833         let rust_vec_inst = m.testarrayofstring().unwrap();
834         let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
835         assert_eq!(rust_vec_iter_collect.len(), 2);
836         assert_eq!(rust_vec_iter_collect[0], "foobar");
837         assert_eq!(rust_vec_iter_collect[1], "baz");
838 
839         let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
840         assert_eq!(rust_vec_iter_rev_collect.len(), 2);
841         assert_eq!(rust_vec_iter_rev_collect[1], "foobar");
842         assert_eq!(rust_vec_iter_rev_collect[0], "baz");
843 
844     }
845     #[test]
vector_of_string_store_manual_build()846     fn vector_of_string_store_manual_build() {
847         let mut b = flatbuffers::FlatBufferBuilder::new();
848         let s0 = b.create_string("foobar");
849         let s1 = b.create_string("baz");
850         let v = b.create_vector(&[s0, s1]);
851         let name = b.create_string("foo");
852         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
853             name: Some(name),
854             testarrayofstring: Some(v), ..Default::default()});
855         assert_eq!(m.testarrayofstring().unwrap().len(), 2);
856         assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
857         assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
858 
859         let rust_vec_inst = m.testarrayofstring().unwrap();
860         let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
861         assert_eq!(rust_vec_iter_collect.len(), 2);
862         assert_eq!(rust_vec_iter_collect[0], "foobar");
863         assert_eq!(rust_vec_iter_collect[1], "baz");
864 
865         let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
866         assert_eq!(rust_vec_iter_rev_collect.len(), 2);
867         assert_eq!(rust_vec_iter_rev_collect[0], "baz");
868         assert_eq!(rust_vec_iter_rev_collect[1], "foobar");
869     }
870     #[test]
vector_of_ubyte_store()871     fn vector_of_ubyte_store() {
872         let mut b = flatbuffers::FlatBufferBuilder::new();
873         let v = b.create_vector(&[123u8, 234u8][..]);
874         let name = b.create_string("foo");
875         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
876             name: Some(name),
877             inventory: Some(v), ..Default::default()});
878         assert_eq!(m.inventory().unwrap(), &[123, 234][..]);
879     }
880     #[test]
vector_of_bool_store()881     fn vector_of_bool_store() {
882         let mut b = flatbuffers::FlatBufferBuilder::new();
883         let v = b.create_vector(&[false, true, false, true][..]);
884         let name = b.create_string("foo");
885         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
886             name: Some(name),
887             testarrayofbools: Some(v), ..Default::default()});
888         assert_eq!(m.testarrayofbools().unwrap(), &[false, true, false, true][..]);
889 
890         let rust_vec_inst = m.testarrayofbools().unwrap();
891         let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
892         assert_eq!(rust_vec_iter_collect, &[&false, &true, &false, &true][..]);
893 
894         let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
895         assert_eq!(rust_vec_iter_rev_collect, &[&true, &false, &true, &false][..]);
896     }
897     #[test]
vector_of_f64_store()898     fn vector_of_f64_store() {
899         let mut b = flatbuffers::FlatBufferBuilder::new();
900         let v = b.create_vector(&[3.14159265359f64][..]);
901         let name = b.create_string("foo");
902         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
903             name: Some(name),
904             vector_of_doubles: Some(v), ..Default::default()});
905         assert_eq!(m.vector_of_doubles().unwrap().len(), 1);
906         assert_eq!(m.vector_of_doubles().unwrap().get(0), 3.14159265359f64);
907 
908         let rust_vec_inst = m.vector_of_doubles().unwrap();
909         let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
910         assert_eq!(rust_vec_iter_collect.len(), 1);
911         assert_eq!(rust_vec_iter_collect[0], 3.14159265359f64);
912 
913         let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
914         assert_eq!(rust_vec_iter_rev_collect.len(), 1);
915         assert_eq!(rust_vec_iter_rev_collect[0], 3.14159265359f64);
916     }
917     #[test]
vector_of_struct_store()918     fn vector_of_struct_store() {
919         let mut b = flatbuffers::FlatBufferBuilder::new();
920         let v = b.create_vector(&[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
921         let name = b.create_string("foo");
922         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
923             name: Some(name),
924             test4: Some(v), ..Default::default()});
925         assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
926 
927         let rust_vec_inst = m.test4().unwrap();
928         let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
929         assert_eq!(rust_vec_iter_collect, &[&my_game::example::Test::new(127, -128), &my_game::example::Test::new(3, 123)][..]);
930 
931         let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
932         assert_eq!(rust_vec_iter_rev_collect, &[&my_game::example::Test::new(3, 123), &my_game::example::Test::new(127, -128)][..]);
933     }
934     #[test]
vector_of_struct_store_with_type_inference()935     fn vector_of_struct_store_with_type_inference() {
936         let mut b = flatbuffers::FlatBufferBuilder::new();
937         let v = b.create_vector(&[my_game::example::Test::new(127, -128),
938                                   my_game::example::Test::new(3, 123),
939                                   my_game::example::Test::new(100, 101)]);
940         let name = b.create_string("foo");
941         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
942             name: Some(name),
943             test4: Some(v), ..Default::default()});
944         assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123), my_game::example::Test::new(100, 101)][..]);
945     }
946      #[test]
vector_of_enums_store()947      fn vector_of_enums_store() {
948          let mut b = flatbuffers::FlatBufferBuilder::new();
949          let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]);
950          let name = b.create_string("foo");
951          let m = build_mon(&mut b, &my_game::example::MonsterArgs{
952              name: Some(name),
953              vector_of_enums: Some(v), ..Default::default()});
954          assert_eq!(m.vector_of_enums().unwrap().len(), 2);
955          assert_eq!(m.vector_of_enums().unwrap().get(0), my_game::example::Color::Red);
956          assert_eq!(m.vector_of_enums().unwrap().get(1), my_game::example::Color::Green);
957      }
958     #[test]
vector_of_table_store()959     fn vector_of_table_store() {
960         let b = &mut flatbuffers::FlatBufferBuilder::new();
961         let t0 = {
962             let name = b.create_string("foo");
963             let args = my_game::example::MonsterArgs{hp: 55, name: Some(name), ..Default::default()};
964             my_game::example::Monster::create(b, &args)
965         };
966         let t1 = {
967             let name = b.create_string("bar");
968             let args = my_game::example::MonsterArgs{name: Some(name), ..Default::default()};
969             my_game::example::Monster::create(b, &args)
970         };
971         let v = b.create_vector(&[t0, t1][..]);
972         let name = b.create_string("foo");
973         let m = build_mon(b, &my_game::example::MonsterArgs{
974             name: Some(name),
975             testarrayoftables: Some(v), ..Default::default()});
976         assert_eq!(m.testarrayoftables().unwrap().len(), 2);
977         assert_eq!(m.testarrayoftables().unwrap().get(0).hp(), 55);
978         assert_eq!(m.testarrayoftables().unwrap().get(0).name(), "foo");
979         assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100);
980         assert_eq!(m.testarrayoftables().unwrap().get(1).name(), "bar");
981 
982         let rust_vec_inst = m.testarrayoftables().unwrap();
983         let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
984         assert_eq!(rust_vec_iter_collect.len(), 2);
985         assert_eq!(rust_vec_iter_collect[0].hp(), 55);
986         assert_eq!(rust_vec_iter_collect[0].name(), "foo");
987         assert_eq!(rust_vec_iter_collect[1].hp(), 100);
988         assert_eq!(rust_vec_iter_collect[1].name(), "bar");
989 
990         let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
991         assert_eq!(rust_vec_iter_rev_collect.len(), 2);
992         assert_eq!(rust_vec_iter_rev_collect[0].hp(), 100);
993         assert_eq!(rust_vec_iter_rev_collect[0].name(), "bar");
994         assert_eq!(rust_vec_iter_rev_collect[1].hp(), 55);
995         assert_eq!(rust_vec_iter_rev_collect[1].name(), "foo");
996     }
997 }
998 
999 #[cfg(test)]
1000 mod generated_code_alignment_and_padding {
1001     extern crate flatbuffers;
1002     use super::my_game;
1003 
1004     #[test]
enum_color_is_1_byte()1005     fn enum_color_is_1_byte() {
1006         assert_eq!(1, ::core::mem::size_of::<my_game::example::Color>());
1007     }
1008 
1009     #[test]
union_any_is_1_byte()1010     fn union_any_is_1_byte() {
1011         assert_eq!(1, ::core::mem::size_of::<my_game::example::Any>());
1012     }
1013 
1014     #[test]
union_any_is_aligned_to_1()1015     fn union_any_is_aligned_to_1() {
1016         assert_eq!(1, ::core::mem::align_of::<my_game::example::Any>());
1017     }
1018     #[test]
struct_test_is_4_bytes()1019     fn struct_test_is_4_bytes() {
1020         assert_eq!(4, ::core::mem::size_of::<my_game::example::Test>());
1021     }
1022     #[test]
struct_vec3_is_32_bytes()1023     fn struct_vec3_is_32_bytes() {
1024         assert_eq!(32, ::core::mem::size_of::<my_game::example::Vec3>());
1025     }
1026 
1027     #[test]
struct_vec3_is_written_with_correct_alignment_in_table()1028     fn struct_vec3_is_written_with_correct_alignment_in_table() {
1029         let b = &mut flatbuffers::FlatBufferBuilder::new();
1030         {
1031             let name = b.create_string("foo");
1032             let mon = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
1033                 name: Some(name),
1034                 pos: Some(&my_game::example::Vec3::new(1.0, 2.0, 3.0, 4.0,
1035                                                        my_game::example::Color::Green,
1036                                                        &my_game::example::Test::new(98, 99))),
1037                                                        ..Default::default()});
1038             my_game::example::finish_monster_buffer(b, mon);
1039         }
1040         let buf = b.finished_data();
1041         let mon = my_game::example::root_as_monster(buf).unwrap();
1042         let vec3 = mon.pos().unwrap();
1043 
1044         let start_ptr = buf.as_ptr() as usize;
1045         let vec3_ptr = vec3 as *const my_game::example::Vec3 as usize;
1046 
1047         assert!(vec3_ptr > start_ptr);
1048         // Vec3 is aligned to 8 wrt the flatbuffer.
1049         assert_eq!((vec3_ptr - start_ptr) % 8, 0);
1050     }
1051 
1052     #[test]
struct_ability_is_8_bytes()1053     fn struct_ability_is_8_bytes() {
1054         assert_eq!(8, ::core::mem::size_of::<my_game::example::Ability>());
1055     }
1056 
1057     #[test]
struct_ability_is_written_with_correct_alignment_in_table_vector()1058     fn struct_ability_is_written_with_correct_alignment_in_table_vector() {
1059         let b = &mut flatbuffers::FlatBufferBuilder::new();
1060         {
1061             let name = b.create_string("foo");
1062             let v = b.create_vector(&[my_game::example::Ability::new(1, 2),
1063                                       my_game::example::Ability::new(3, 4),
1064                                       my_game::example::Ability::new(5, 6)]);
1065             let mon = my_game::example::Monster::create(b, &my_game::example::MonsterArgs{
1066                 name: Some(name),
1067                 testarrayofsortedstruct: Some(v),
1068                 ..Default::default()});
1069             my_game::example::finish_monster_buffer(b, mon);
1070         }
1071         let buf = b.finished_data();
1072         let mon = my_game::example::root_as_monster(buf).unwrap();
1073         let abilities = mon.testarrayofsortedstruct().unwrap();
1074 
1075         let start_ptr = buf.as_ptr() as usize;
1076         for a in abilities.iter() {
1077             let a_ptr = a as *const my_game::example::Ability as usize;
1078             assert!(a_ptr > start_ptr);
1079             let aln = ::core::mem::align_of::<my_game::example::Ability>();
1080             assert_eq!((a_ptr - start_ptr) % aln, 0);
1081         }
1082         for a in abilities.iter().rev() {
1083             let a_ptr = a as *const my_game::example::Ability as usize;
1084             assert!(a_ptr > start_ptr);
1085             // Vec3 is aligned to 8 wrt the flatbuffer.
1086             assert_eq!((a_ptr - start_ptr) % 8, 0);
1087         }
1088     }
1089 }
1090 
1091 #[cfg(test)]
1092 mod roundtrip_byteswap {
1093     #[cfg(not(miri))]  // slow.
1094     extern crate quickcheck;
1095     extern crate flatbuffers;
1096 
1097     const N: u64 = 10000;
1098 
palindrome_32(x: f32) -> bool1099     fn palindrome_32(x: f32) -> bool {
1100         x == f32::from_bits(x.to_bits().swap_bytes())
1101     }
palindrome_64(x: f64) -> bool1102     fn palindrome_64(x: f64) -> bool {
1103         x == f64::from_bits(x.to_bits().swap_bytes())
1104     }
1105 
prop_f32(x: f32)1106     fn prop_f32(x: f32) {
1107         use flatbuffers::byte_swap_f32;
1108 
1109         let there = byte_swap_f32(x);
1110 
1111         let back_again = byte_swap_f32(there);
1112 
1113         if !palindrome_32(x) {
1114             assert!(x != there);
1115         }
1116 
1117         assert_eq!(x, back_again);
1118     }
1119 
prop_f64(x: f64)1120     fn prop_f64(x: f64) {
1121         use flatbuffers::byte_swap_f64;
1122 
1123         let there = byte_swap_f64(x);
1124         let back_again = byte_swap_f64(there);
1125 
1126         if !palindrome_64(x) {
1127             assert!(x != there);
1128         }
1129 
1130         assert_eq!(x, back_again);
1131     }
1132 
1133     // TODO(rw): Replace the implementations with the new stdlib endian-conversion functions.
1134     // TODO(rw): Re-enable these tests (currently, rare CI failures occur that seem spurious).
1135     // #[test]
1136     // fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
1137     // #[test]
1138     // fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
1139 }
1140 
1141 #[cfg(not(miri))]
1142 quickcheck! {
1143   fn struct_of_structs(
1144     a_id: u32,
1145     a_distance: u32,
1146     b_a: i16,
1147     b_b: i8,
1148     c_id: u32,
1149     c_distance: u32
1150   ) -> bool {
1151     use my_game::example::*;
1152     let mut sos = StructOfStructs::default();
1153     let mut a = Ability::default();
1154     a.set_id(a_id);
1155     a.set_distance(a_distance);
1156     let mut b = Test::default();
1157     b.set_a(b_a);
1158     b.set_b(b_b);
1159     let mut c = Ability::default();
1160     c.set_id(c_id);
1161     c.set_distance(c_distance);
1162     sos.set_a(&a);
1163     sos.set_b(&b);
1164     sos.set_c(&c);
1165 
1166     sos.a().id() == a_id &&
1167     sos.a().distance() == a_distance &&
1168     sos.b().a() == b_a &&
1169     sos.b().b() == b_b &&
1170     sos.c().id() == c_id &&
1171     sos.c().distance() == c_distance
1172   }
1173 }
1174 
1175 #[cfg(not(miri))]  // slow.
1176 #[cfg(test)]
1177 mod roundtrip_vectors {
1178 
1179     #[cfg(test)]
1180     mod scalar {
1181         extern crate quickcheck;
1182         extern crate flatbuffers;
1183 
1184         use alloc::vec::Vec;
1185 
1186         const N: u64 = 20;
1187 
prop<T>(xs: Vec<T>) where T: for<'a> flatbuffers::Follow<'a, Inner = T> + flatbuffers::EndianScalar + flatbuffers::Push + ::core::fmt::Debug,1188         fn prop<T>(xs: Vec<T>)
1189         where
1190             T: for<'a> flatbuffers::Follow<'a, Inner = T>
1191                 + flatbuffers::EndianScalar
1192                 + flatbuffers::Push
1193                 + ::core::fmt::Debug,
1194         {
1195             use flatbuffers::Follow;
1196 
1197             let mut b = flatbuffers::FlatBufferBuilder::new();
1198             b.start_vector::<T>(xs.len());
1199             for i in (0..xs.len()).rev() {
1200                 b.push::<T>(xs[i]);
1201             }
1202             let vecend = b.end_vector::<T>(xs.len());
1203             b.finish_minimal(vecend);
1204 
1205             let buf = b.finished_data();
1206 
1207             let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<T>>>::follow(&buf[..], 0);
1208             let mut result_vec: Vec<T> = Vec::with_capacity(got.len());
1209             for i in 0..got.len() {
1210                 result_vec.push(got.get(i));
1211             }
1212             assert_eq!(result_vec, xs);
1213 
1214             let rust_vec_iter = got.iter().collect::<Vec<T>>();
1215             assert_eq!(rust_vec_iter, xs);
1216 
1217             let mut rust_vec_rev_iter = got.iter().rev().collect::<Vec<T>>();
1218             rust_vec_rev_iter.reverse();
1219             assert_eq!(rust_vec_rev_iter, xs);
1220         }
1221 
1222         #[test]
easy_u8()1223         fn easy_u8() {
1224             prop::<u8>(vec![]);
1225             prop::<u8>(vec![1u8]);
1226             prop::<u8>(vec![1u8, 2u8]);
1227             prop::<u8>(vec![1u8, 2u8, 3u8]);
1228             prop::<u8>(vec![1u8, 2u8, 3u8, 4u8]);
1229         }
1230 
1231         #[test]
fuzz_bool()1232         fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<bool> as fn(Vec<_>)); }
1233         #[test]
fuzz_u8()1234         fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u8> as fn(Vec<_>)); }
1235         #[test]
fuzz_i8()1236         fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i8> as fn(Vec<_>)); }
1237         #[test]
fuzz_u16()1238         fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u16> as fn(Vec<_>)); }
1239         #[test]
fuzz_i16()1240         fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i16> as fn(Vec<_>)); }
1241         #[test]
fuzz_u32()1242         fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u32> as fn(Vec<_>)); }
1243         #[test]
fuzz_i32()1244         fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i32> as fn(Vec<_>)); }
1245         #[test]
fuzz_u64()1246         fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u64> as fn(Vec<_>)); }
1247         #[test]
fuzz_i64()1248         fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i64> as fn(Vec<_>)); }
1249         #[test]
fuzz_f32()1250         fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f32> as fn(Vec<_>)); }
1251         #[test]
fuzz_f64()1252         fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f64> as fn(Vec<_>)); }
1253     }
1254 
1255     #[cfg(test)]
1256     mod create_vector_direct {
1257         #[cfg(not(miri))]  // slow.
1258         extern crate quickcheck;
1259         extern crate flatbuffers;
1260 
1261         const N: u64 = 20;
1262 
1263         // This uses a macro because lifetimes for the trait-bounded function get too
1264         // complicated.
1265         macro_rules! impl_prop {
1266             ($test_name:ident, $fn_name:ident, $ty:ident) => (
1267                 fn $fn_name(xs: alloc::vec::Vec<$ty>) {
1268                     use flatbuffers::Follow;
1269 
1270                     let mut b = flatbuffers::FlatBufferBuilder::new();
1271                     b.create_vector_direct(&xs[..]);
1272                     let buf = b.unfinished_data();
1273 
1274                     let got = <flatbuffers::Vector<$ty>>::follow(&buf[..], 0).safe_slice();
1275                     assert_eq!(got, &xs[..]);
1276                 }
1277                 #[test]
1278                 fn $test_name() { quickcheck::QuickCheck::new().max_tests(N).quickcheck($fn_name as fn(alloc::vec::Vec<_>)); }
1279             )
1280         }
1281 
1282         impl_prop!(test_bool, prop_bool, bool);
1283         impl_prop!(test_u8, prop_u8, u8);
1284         impl_prop!(test_i8, prop_i8, i8);
1285 
1286         #[cfg(test)]
1287         #[cfg(target_endian = "little")]
1288         mod host_is_le {
1289             const N: u64 = 20;
1290             use super::flatbuffers;
1291             use super::quickcheck;
1292             impl_prop!(test_u16, prop_u16, u16);
1293             impl_prop!(test_u32, prop_u32, u32);
1294             impl_prop!(test_u64, prop_u64, u64);
1295             impl_prop!(test_i16, prop_i16, i16);
1296             impl_prop!(test_i32, prop_i32, i32);
1297             impl_prop!(test_i64, prop_i64, i64);
1298             impl_prop!(test_f32, prop_f32, f32);
1299             impl_prop!(test_f64, prop_f64, f64);
1300         }
1301     }
1302 
1303     #[cfg(test)]
1304     mod string_manual_build {
1305         #[cfg(not(miri))]  // slow.
1306         extern crate quickcheck;
1307         extern crate flatbuffers;
1308 
1309         use alloc::string::String;
1310         use alloc::vec::Vec;
1311 
prop(xs: Vec<String>)1312         fn prop(xs: Vec<String>) {
1313             use flatbuffers::Follow;
1314 
1315             let mut b = flatbuffers::FlatBufferBuilder::new();
1316             let mut offsets = Vec::new();
1317             for s in xs.iter().rev() {
1318                 offsets.push(b.create_string(s.as_str()));
1319             }
1320 
1321             b.start_vector::<flatbuffers::WIPOffset<&str>>(xs.len());
1322             for &i in offsets.iter() {
1323                 b.push(i);
1324             }
1325             let vecend = b.end_vector::<flatbuffers::WIPOffset<&str>>(xs.len());
1326 
1327             b.finish_minimal(vecend);
1328 
1329             let buf = b.finished_data();
1330             let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>>>::follow(buf, 0);
1331 
1332             assert_eq!(got.len(), xs.len());
1333             for i in 0..xs.len() {
1334                 assert_eq!(got.get(i), &xs[i][..]);
1335             }
1336         }
1337 
1338         #[test]
fuzz()1339         fn fuzz() {
1340             quickcheck::QuickCheck::new().max_tests(20).quickcheck(prop as fn(Vec<_>));
1341         }
1342     }
1343 
1344     #[cfg(test)]
1345     mod string_helper_build {
1346         #[cfg(not(miri))]  // slow.
1347         extern crate quickcheck;
1348         extern crate flatbuffers;
1349 
1350         use alloc::string::String;
1351         use alloc::vec::Vec;
1352 
prop(input: Vec<String>)1353         fn prop(input: Vec<String>) {
1354             let xs: Vec<&str> = input.iter().map(|s: &String| &s[..]).collect();
1355 
1356             use flatbuffers::Follow;
1357 
1358             let mut b = flatbuffers::FlatBufferBuilder::new();
1359             let vecend = b.create_vector_of_strings(&xs[..]);
1360 
1361             b.finish_minimal(vecend);
1362 
1363             let buf = b.finished_data();
1364             let got = <flatbuffers::ForwardsUOffset<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>>>::follow(buf, 0);
1365 
1366             assert_eq!(got.len(), xs.len());
1367             for i in 0..xs.len() {
1368                 assert_eq!(got.get(i), &xs[i][..]);
1369             }
1370         }
1371 
1372         #[test]
fuzz()1373         fn fuzz() {
1374             quickcheck::QuickCheck::new().max_tests(100).quickcheck(prop as fn(Vec<_>));
1375         }
1376     }
1377 
1378     #[cfg(test)]
1379     mod ubyte {
1380         #[cfg(not(miri))]  // slow.
1381         extern crate quickcheck;
1382         extern crate flatbuffers;
1383 
1384         use alloc::vec::Vec;
1385 
1386         #[cfg(not(miri))]  // slow.
1387         #[test]
fuzz_manual_build()1388         fn fuzz_manual_build() {
1389             fn prop(vec: Vec<u8>) {
1390                 let xs = &vec[..];
1391 
1392                 let mut b1 = flatbuffers::FlatBufferBuilder::new();
1393                 b1.start_vector::<u8>(xs.len());
1394 
1395                 for i in (0..xs.len()).rev() {
1396                     b1.push(xs[i]);
1397                 }
1398                 b1.end_vector::<u8>(xs.len());
1399 
1400                 let mut b2 = flatbuffers::FlatBufferBuilder::new();
1401                 b2.create_vector(xs);
1402                 assert_eq!(b1.unfinished_data(), b2.unfinished_data());
1403             }
1404             quickcheck::QuickCheck::new().max_tests(100).quickcheck(prop as fn(Vec<_>));
1405         }
1406     }
1407 }
1408 
1409 #[cfg(test)]
1410 mod framing_format {
1411     extern crate flatbuffers;
1412 
1413     use super::my_game;
1414 
1415     #[test]
test_size_prefixed_buffer()1416     fn test_size_prefixed_buffer() {
1417         // Create size prefixed buffer.
1418         let mut b = flatbuffers::FlatBufferBuilder::new();
1419         let args = &my_game::example::MonsterArgs{
1420             mana: 200,
1421             hp: 300,
1422             name: Some(b.create_string("bob")),
1423             ..Default::default()
1424         };
1425         let mon = my_game::example::Monster::create(&mut b, &args);
1426         b.finish_size_prefixed(mon, None);
1427 
1428         // Access it.
1429         let buf = b.finished_data();
1430         let m = flatbuffers::size_prefixed_root::<my_game::example::Monster>(buf).unwrap();
1431         assert_eq!(m.mana(), 200);
1432         assert_eq!(m.hp(), 300);
1433         assert_eq!(m.name(), "bob");
1434     }
1435 }
1436 
1437 #[cfg(not(feature = "no_std"))]
1438 #[cfg(test)]
1439 mod roundtrip_table {
1440     use alloc::string::String;
1441     use alloc::vec::Vec;
1442     use std::collections::HashMap;
1443 
1444     extern crate flatbuffers;
1445     #[cfg(not(miri))]  // slow.
1446     extern crate quickcheck;
1447 
1448     use super::LCG;
1449 
1450     #[test]
1451     #[cfg(not(miri))]  // slow.
table_of_mixed_scalars_fuzz()1452     fn table_of_mixed_scalars_fuzz() {
1453         // Values we're testing against: chosen to ensure no bits get chopped
1454         // off anywhere, and also be different from eachother.
1455         let bool_val: bool = true;
1456         let char_val: i8 = -127;  // 0x81
1457         let uchar_val: u8 = 0xFF;
1458         let short_val: i16 = -32222;  // 0x8222;
1459         let ushort_val: u16 = 0xFEEE;
1460         let int_val: i32 = unsafe { ::core::mem::transmute(0x83333333u32) };
1461         let uint_val: u32 = 0xFDDDDDDD;
1462         let long_val: i64 = unsafe { ::core::mem::transmute(0x8444444444444444u64) }; // TODO: byte literal?
1463         let ulong_val: u64 = 0xFCCCCCCCCCCCCCCCu64;
1464         let float_val: f32 = 3.14159;
1465         let double_val: f64 = 3.14159265359;
1466 
1467         let test_value_types_max: isize = 11;
1468         let max_fields_per_object: flatbuffers::VOffsetT = 100;
1469         let num_fuzz_objects: isize = 1000;  // The higher, the more thorough :)
1470 
1471         let mut builder = flatbuffers::FlatBufferBuilder::new();
1472         let mut lcg = LCG::new();
1473 
1474         let mut objects: Vec<flatbuffers::UOffsetT> = vec![0; num_fuzz_objects as usize];
1475 
1476         // Generate num_fuzz_objects random objects each consisting of
1477         // fields_per_object fields, each of a random type.
1478         for i in 0..(num_fuzz_objects as usize) {
1479             let fields_per_object = (lcg.next() % (max_fields_per_object as u64)) as flatbuffers::VOffsetT;
1480             let start = builder.start_table();
1481 
1482             for j in 0..fields_per_object {
1483                 let choice = lcg.next() % (test_value_types_max as u64);
1484 
1485                 let f = flatbuffers::field_index_to_field_offset(j);
1486 
1487                 match choice {
1488                     0 => {builder.push_slot::<bool>(f, bool_val, false);}
1489                     1 => {builder.push_slot::<i8>(f, char_val, 0);}
1490                     2 => {builder.push_slot::<u8>(f, uchar_val, 0);}
1491                     3 => {builder.push_slot::<i16>(f, short_val, 0);}
1492                     4 => {builder.push_slot::<u16>(f, ushort_val, 0);}
1493                     5 => {builder.push_slot::<i32>(f, int_val, 0);}
1494                     6 => {builder.push_slot::<u32>(f, uint_val, 0);}
1495                     7 => {builder.push_slot::<i64>(f, long_val, 0);}
1496                     8 => {builder.push_slot::<u64>(f, ulong_val, 0);}
1497                     9 => {builder.push_slot::<f32>(f, float_val, 0.0);}
1498                     10 => {builder.push_slot::<f64>(f, double_val, 0.0);}
1499                     _ => { panic!("unknown choice: {}", choice); }
1500                 }
1501             }
1502             objects[i] = builder.end_table(start).value();
1503         }
1504 
1505         // Do some bookkeeping to generate stats on fuzzes:
1506         let mut stats: HashMap<u64, u64> = HashMap::new();
1507         let mut values_generated: u64 = 0;
1508 
1509         // Embrace PRNG determinism:
1510         lcg.reset();
1511 
1512         // Test that all objects we generated are readable and return the
1513         // expected values. We generate random objects in the same order
1514         // so this is deterministic:
1515         for i in 0..(num_fuzz_objects as usize) {
1516             let table = {
1517                 let buf = builder.unfinished_data();
1518                 let loc = buf.len() as flatbuffers::UOffsetT - objects[i];
1519                 flatbuffers::Table::new(buf, loc as usize)
1520             };
1521 
1522             let fields_per_object = (lcg.next() % (max_fields_per_object as u64)) as flatbuffers::VOffsetT;
1523             for j in 0..fields_per_object {
1524                 let choice = lcg.next() % (test_value_types_max as u64);
1525 
1526                 *stats.entry(choice).or_insert(0) += 1;
1527                 values_generated += 1;
1528 
1529                 let f = flatbuffers::field_index_to_field_offset(j);
1530 
1531                 match choice {
1532                     0 => { assert_eq!(bool_val, table.get::<bool>(f, Some(false)).unwrap()); }
1533                     1 => { assert_eq!(char_val, table.get::<i8>(f, Some(0)).unwrap()); }
1534                     2 => { assert_eq!(uchar_val, table.get::<u8>(f, Some(0)).unwrap()); }
1535                     3 => { assert_eq!(short_val, table.get::<i16>(f, Some(0)).unwrap()); }
1536                     4 => { assert_eq!(ushort_val, table.get::<u16>(f, Some(0)).unwrap()); }
1537                     5 => { assert_eq!(int_val, table.get::<i32>(f, Some(0)).unwrap()); }
1538                     6 => { assert_eq!(uint_val, table.get::<u32>(f, Some(0)).unwrap()); }
1539                     7 => { assert_eq!(long_val, table.get::<i64>(f, Some(0)).unwrap()); }
1540                     8 => { assert_eq!(ulong_val, table.get::<u64>(f, Some(0)).unwrap()); }
1541                     9 => { assert_eq!(float_val, table.get::<f32>(f, Some(0.0)).unwrap()); }
1542                     10 => { assert_eq!(double_val, table.get::<f64>(f, Some(0.0)).unwrap()); }
1543                     _ => { panic!("unknown choice: {}", choice); }
1544                 }
1545             }
1546         }
1547 
1548         // Assert that we tested all the fuzz cases enough:
1549         let min_tests_per_choice = 1000;
1550         assert!(values_generated > 0);
1551         assert!(min_tests_per_choice > 0);
1552         for i in 0..test_value_types_max as u64 {
1553             assert!(stats[&i] >= min_tests_per_choice, "inadequately-tested fuzz case: {}", i);
1554         }
1555     }
1556 
1557     #[test]
1558     #[cfg(not(miri))]  // slow.
table_of_byte_strings_fuzz()1559     fn table_of_byte_strings_fuzz() {
1560         fn prop(vec: Vec<Vec<u8>>) {
1561             use flatbuffers::field_index_to_field_offset as fi2fo;
1562             use flatbuffers::Follow;
1563 
1564             let xs = &vec[..];
1565 
1566             // build
1567             let mut b = flatbuffers::FlatBufferBuilder::new();
1568             let str_offsets: Vec<flatbuffers::WIPOffset<_>> = xs.iter().map(|s| b.create_byte_string(&s[..])).collect();
1569             let table_start = b.start_table();
1570 
1571             for i in 0..xs.len() {
1572                 b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), str_offsets[i]);
1573             }
1574             let root = b.end_table(table_start);
1575             b.finish_minimal(root);
1576 
1577             // use
1578             let buf = b.finished_data();
1579             let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
1580 
1581             for i in 0..xs.len() {
1582                 let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(i as flatbuffers::VOffsetT), None);
1583                 assert!(v.is_some());
1584                 let v2 = v.unwrap().safe_slice();
1585                 assert_eq!(v2, &xs[i][..]);
1586             }
1587         }
1588         prop(vec![vec![1,2,3]]);
1589 
1590         let n = 20;
1591         quickcheck::QuickCheck::new().max_tests(n).quickcheck(prop as fn(Vec<_>));
1592     }
1593 
1594     #[test]
1595     #[cfg(not(miri))]  // slow.
fuzz_table_of_strings()1596     fn fuzz_table_of_strings() {
1597         fn prop(vec: Vec<String>) {
1598             use flatbuffers::field_index_to_field_offset as fi2fo;
1599             use flatbuffers::Follow;
1600 
1601             let xs = &vec[..];
1602 
1603             // build
1604             let mut b = flatbuffers::FlatBufferBuilder::new();
1605             let str_offsets: Vec<flatbuffers::WIPOffset<_>> = xs.iter().map(|s| b.create_string(&s[..])).collect();
1606             let table_start = b.start_table();
1607 
1608             for i in 0..xs.len() {
1609                 b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), str_offsets[i]);
1610             }
1611             let root = b.end_table(table_start);
1612             b.finish_minimal(root);
1613 
1614             // use
1615             let buf = b.finished_data();
1616             let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
1617 
1618             for i in 0..xs.len() {
1619                 let v = tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(i as flatbuffers::VOffsetT), None);
1620                 assert_eq!(v, Some(&xs[i][..]));
1621             }
1622         }
1623         let n = 20;
1624         quickcheck::QuickCheck::new().max_tests(n).quickcheck(prop as fn(Vec<String>));
1625     }
1626 
1627     #[cfg(not(miri))]  // slow.
1628     mod table_of_vectors_of_scalars {
1629 
1630         use alloc::vec::Vec;
1631 
1632         extern crate flatbuffers;
1633         #[cfg(not(miri))]  // slow.
1634         extern crate quickcheck;
1635 
1636         const N: u64 = 20;
1637 
prop<T>(vecs: Vec<Vec<T>>) where T: for<'a> flatbuffers::Follow<'a, Inner = T> + flatbuffers::EndianScalar + flatbuffers::Push + ::core::fmt::Debug,1638         fn prop<T>(vecs: Vec<Vec<T>>)
1639         where
1640             T: for<'a> flatbuffers::Follow<'a, Inner = T>
1641                 + flatbuffers::EndianScalar
1642                 + flatbuffers::Push
1643                 + ::core::fmt::Debug,
1644         {
1645             use flatbuffers::field_index_to_field_offset as fi2fo;
1646             use flatbuffers::Follow;
1647 
1648             // build
1649             let mut b = flatbuffers::FlatBufferBuilder::new();
1650             let mut offs = vec![];
1651             for vec in &vecs {
1652                 b.start_vector::<T>(vec.len());
1653 
1654                 let xs = &vec[..];
1655                 for i in (0..xs.len()).rev() {
1656                     b.push::<T>(xs[i]);
1657                 }
1658                 let vecend = b.end_vector::<T>(xs.len());
1659                 offs.push(vecend);
1660             }
1661 
1662             let table_start = b.start_table();
1663 
1664             for i in 0..vecs.len() {
1665                 b.push_slot_always(fi2fo(i as flatbuffers::VOffsetT), offs[i]);
1666             }
1667             let root = b.end_table(table_start);
1668             b.finish_minimal(root);
1669 
1670             // use
1671             let buf = b.finished_data();
1672             let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(buf, 0);
1673 
1674             for i in 0..vecs.len() {
1675                 let got = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<T>>>(fi2fo(i as flatbuffers::VOffsetT), None);
1676                 assert!(got.is_some());
1677                 let got2 = got.unwrap();
1678                 let mut got3: Vec<T> = Vec::with_capacity(got2.len());
1679                 for i in 0..got2.len() {
1680                     got3.push(got2.get(i));
1681                 }
1682                 assert_eq!(vecs[i], got3);
1683             }
1684         }
1685 
1686         #[test]
fuzz_bool()1687         fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<bool>>)); }
1688 
1689         #[test]
fuzz_u8()1690         fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u8>>)); }
1691         #[test]
fuzz_u16()1692         fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u16>>)); }
1693         #[test]
fuzz_u32()1694         fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u32>>)); }
1695         #[test]
fuzz_u64()1696         fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u64>>)); }
1697 
1698         #[test]
fuzz_i8()1699         fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u8>>)); }
1700         #[test]
fuzz_i16()1701         fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u16>>)); }
1702         #[test]
fuzz_i32()1703         fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u32>>)); }
1704         #[test]
fuzz_i64()1705         fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<u64>>)); }
1706 
1707         #[test]
fuzz_f32()1708         fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<f32>>)); }
1709         #[test]
fuzz_f64()1710         fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop as fn(Vec<Vec<f64>>)); }
1711     }
1712 }
1713 
1714 #[cfg(not(miri))]  // slow.
1715 #[cfg(test)]
1716 mod roundtrip_scalars {
1717     extern crate flatbuffers;
1718     #[cfg(not(miri))]  // slow.
1719     extern crate quickcheck;
1720 
1721     const N: u64 = 1000;
1722 
prop<T: PartialEq + ::core::fmt::Debug + Copy + flatbuffers::EndianScalar>(x: T)1723     fn prop<T: PartialEq + ::core::fmt::Debug + Copy + flatbuffers::EndianScalar>(x: T) {
1724         let mut buf = vec![0u8; ::core::mem::size_of::<T>()];
1725         let y = unsafe {
1726             flatbuffers::emplace_scalar(&mut buf[..], x);
1727             flatbuffers::read_scalar(&buf[..])
1728         };
1729         assert_eq!(x, y);
1730     }
1731 
1732     #[test]
fuzz_bool()1733     fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<bool> as fn(_)); }
1734     #[test]
fuzz_u8()1735     fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u8> as fn(_)); }
1736     #[test]
fuzz_i8()1737     fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i8> as fn(_)); }
1738 
1739     #[test]
fuzz_u16()1740     fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u16> as fn(_)); }
1741     #[test]
fuzz_i16()1742     fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i16> as fn(_)); }
1743 
1744     #[test]
fuzz_u32()1745     fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u32> as fn(_)); }
1746     #[test]
fuzz_i32()1747     fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i32> as fn(_)); }
1748 
1749     #[test]
fuzz_u64()1750     fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<u64> as fn(_)); }
1751     #[test]
fuzz_i64()1752     fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<i64> as fn(_)); }
1753 
1754     #[test]
fuzz_f32()1755     fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f32> as fn(_)); }
1756     #[test]
fuzz_f64()1757     fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop::<f64> as fn(_)); }
1758 }
1759 
1760 #[cfg(test)]
1761 #[cfg(not(miri))]  // slow.
1762 mod roundtrip_push_follow_scalars {
1763     extern crate flatbuffers;
1764     #[cfg(not(miri))]  // slow.
1765     extern crate quickcheck;
1766 
1767     use flatbuffers::Push;
1768 
1769     const N: u64 = 1000;
1770 
1771     // This uses a macro because lifetimes for a trait-bounded function get too
1772     // complicated.
1773     macro_rules! impl_prop {
1774         ($fn_name:ident, $ty:ident) => (
1775             fn $fn_name(x: $ty) {
1776                 let mut buf = vec![0u8; ::core::mem::size_of::<$ty>()];
1777                 x.push(&mut buf[..], &[][..]);
1778                 let fs: flatbuffers::FollowStart<$ty> = flatbuffers::FollowStart::new();
1779                 assert_eq!(fs.self_follow(&buf[..], 0), x);
1780             }
1781         )
1782     }
1783 
1784     impl_prop!(prop_bool, bool);
1785     impl_prop!(prop_u8, u8);
1786     impl_prop!(prop_i8, i8);
1787     impl_prop!(prop_u16, u16);
1788     impl_prop!(prop_i16, i16);
1789     impl_prop!(prop_u32, u32);
1790     impl_prop!(prop_i32, i32);
1791     impl_prop!(prop_u64, u64);
1792     impl_prop!(prop_i64, i64);
1793     impl_prop!(prop_f32, f32);
1794     impl_prop!(prop_f64, f64);
1795 
1796     #[test]
fuzz_bool()1797     fn fuzz_bool() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_bool as fn(bool)); }
1798     #[test]
fuzz_u8()1799     fn fuzz_u8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u8 as fn(u8)); }
1800     #[test]
fuzz_i8()1801     fn fuzz_i8() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i8 as fn(i8)); }
1802     #[test]
fuzz_u16()1803     fn fuzz_u16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u16 as fn(u16)); }
1804     #[test]
fuzz_i16()1805     fn fuzz_i16() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i16 as fn(i16)); }
1806     #[test]
fuzz_u32()1807     fn fuzz_u32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u32 as fn(u32)); }
1808     #[test]
fuzz_i32()1809     fn fuzz_i32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i32 as fn(i32)); }
1810     #[test]
fuzz_u64()1811     fn fuzz_u64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_u64 as fn(u64)); }
1812     #[test]
fuzz_i64()1813     fn fuzz_i64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_i64 as fn(i64)); }
1814     #[test]
fuzz_f32()1815     fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
1816     #[test]
fuzz_f64()1817     fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
1818 }
1819 
1820 
1821 #[cfg(test)]
1822 mod write_and_read_examples {
1823     extern crate flatbuffers;
1824 
1825     use super::create_serialized_example_with_library_code;
1826     use super::create_serialized_example_with_generated_code;
1827     use super::serialized_example_is_accessible_and_correct;
1828 
1829     #[test]
generated_code_creates_correct_example()1830     fn generated_code_creates_correct_example() {
1831         let b = &mut flatbuffers::FlatBufferBuilder::new();
1832         create_serialized_example_with_generated_code(b);
1833         let buf = b.finished_data();
1834         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1835     }
1836 
1837     #[test]
generated_code_debug_prints_correctly()1838     fn generated_code_debug_prints_correctly() {
1839         let b = &mut flatbuffers::FlatBufferBuilder::new();
1840         create_serialized_example_with_generated_code(b);
1841         let buf = b.finished_data();
1842         serialized_example_is_accessible_and_correct(&buf, true, false).unwrap();
1843         let m = super::my_game::example::root_as_monster(buf).unwrap();
1844         assert_eq!(
1845             format!("{:.5?}", &m),
1846             "Monster { pos: Some(Vec3 { x: 1.00000, y: 2.00000, z: 3.00000, \
1847             test1: 3.00000, test2: Green, test3: Test { a: 5, b: 6 } }), \
1848             mana: 150, hp: 80, name: \"MyMonster\", \
1849             inventory: Some([0, 1, 2, 3, 4]), color: Blue, test_type: Monster, \
1850             test: Monster { pos: None, mana: 150, hp: 100, name: \"Fred\", \
1851             inventory: None, color: Blue, test_type: NONE, test: None, \
1852             test4: None, testarrayofstring: None, testarrayoftables: None, \
1853             enemy: None, testnestedflatbuffer: None, testempty: None, \
1854             testbool: false, testhashs32_fnv1: 0, testhashu32_fnv1: 0, \
1855             testhashs64_fnv1: 0, testhashu64_fnv1: 0, testhashs32_fnv1a: 0, \
1856             testhashu32_fnv1a: 0, testhashs64_fnv1a: 0, testhashu64_fnv1a: 0, \
1857             testarrayofbools: None, testf: 3.14159, testf2: 3.00000, testf3: 0.00000, \
1858             testarrayofstring2: None, testarrayofsortedstruct: None, flex: None, \
1859             test5: None, vector_of_longs: None, vector_of_doubles: None, \
1860             parent_namespace_test: None, vector_of_referrables: None, \
1861             single_weak_reference: 0, vector_of_weak_references: None, \
1862             vector_of_strong_referrables: None, co_owning_reference: 0, \
1863             vector_of_co_owning_references: None, non_owning_reference: 0, \
1864             vector_of_non_owning_references: None, any_unique_type: NONE, \
1865             any_unique: None, any_ambiguous_type: NONE, any_ambiguous: None, \
1866             vector_of_enums: None, signed_enum: None, \
1867             testrequirednestedflatbuffer: None, scalar_key_sorted_tables: None, \
1868             native_inline: None, long_enum_non_enum_default: (empty), \
1869             long_enum_normal_default: LongOne }, \
1870             test4: Some([Test { a: 10, b: 20 }, Test { a: 30, b: 40 }]), \
1871             testarrayofstring: Some([\"test1\", \"test2\"]), \
1872             testarrayoftables: None, enemy: None, testnestedflatbuffer: None, \
1873             testempty: None, testbool: false, testhashs32_fnv1: 0, \
1874             testhashu32_fnv1: 0, testhashs64_fnv1: 0, testhashu64_fnv1: 0, \
1875             testhashs32_fnv1a: 0, testhashu32_fnv1a: 0, testhashs64_fnv1a: 0, \
1876             testhashu64_fnv1a: 0, testarrayofbools: None, testf: 3.14159, \
1877             testf2: 3.00000, testf3: 0.00000, testarrayofstring2: None, \
1878             testarrayofsortedstruct: None, flex: None, test5: None, \
1879             vector_of_longs: None, vector_of_doubles: None, \
1880             parent_namespace_test: None, vector_of_referrables: None, \
1881             single_weak_reference: 0, vector_of_weak_references: None, \
1882             vector_of_strong_referrables: None, co_owning_reference: 0, \
1883             vector_of_co_owning_references: None, non_owning_reference: 0, \
1884             vector_of_non_owning_references: None, any_unique_type: NONE, \
1885             any_unique: None, any_ambiguous_type: NONE, any_ambiguous: None, \
1886             vector_of_enums: None, signed_enum: None, \
1887             testrequirednestedflatbuffer: None, scalar_key_sorted_tables: None, \
1888             native_inline: None, long_enum_non_enum_default: (empty), \
1889             long_enum_normal_default: LongOne }"
1890         );
1891     }
1892 
1893     #[test]
1894     #[cfg(not(miri))]  // slow.
generated_code_creates_correct_example_repeatedly_with_reset()1895     fn generated_code_creates_correct_example_repeatedly_with_reset() {
1896         let b = &mut flatbuffers::FlatBufferBuilder::new();
1897         for _ in 0..100 {
1898             create_serialized_example_with_generated_code(b);
1899             {
1900                 let buf = b.finished_data();
1901                 serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1902             }
1903             b.reset();
1904         }
1905     }
1906 
1907     #[test]
library_code_creates_correct_example()1908     fn library_code_creates_correct_example() {
1909         let b = &mut flatbuffers::FlatBufferBuilder::new();
1910         create_serialized_example_with_library_code(b);
1911         let buf = b.finished_data();
1912         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1913     }
1914 
1915     #[test]
1916     #[cfg(not(miri))]  // slow.
library_code_creates_correct_example_repeatedly_with_reset()1917     fn library_code_creates_correct_example_repeatedly_with_reset() {
1918         let b = &mut flatbuffers::FlatBufferBuilder::new();
1919         for _ in 0..100 {
1920             create_serialized_example_with_library_code(b);
1921             {
1922                 let buf = b.finished_data();
1923                 serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1924             }
1925             b.reset();
1926         }
1927     }
1928 }
1929 
1930 #[cfg(not(feature = "no_std"))]
1931 #[cfg(test)]
1932 mod read_examples_from_other_language_ports {
1933     extern crate flatbuffers;
1934 
1935     use std::println;
1936 
1937     use super::load_file;
1938     use super::serialized_example_is_accessible_and_correct;
1939 
1940     #[test]
gold_cpp_example_data_is_accessible_and_correct()1941     fn gold_cpp_example_data_is_accessible_and_correct() {
1942         let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
1943         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1944     }
1945     #[test]
java_wire_example_data_is_accessible_and_correct()1946     fn java_wire_example_data_is_accessible_and_correct() {
1947         let buf = load_file("../monsterdata_java_wire.mon");
1948         if buf.is_err() {
1949             println!("skipping java wire test because it is not present");
1950             return;
1951         }
1952         let buf = buf.unwrap();
1953         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1954     }
1955     #[test]
java_wire_size_prefixed_example_data_is_accessible_and_correct()1956     fn java_wire_size_prefixed_example_data_is_accessible_and_correct() {
1957         let buf = load_file("../monsterdata_java_wire_sp.mon");
1958         if buf.is_err() {
1959             println!("skipping java wire test because it is not present");
1960             return;
1961         }
1962         let buf = buf.unwrap();
1963         serialized_example_is_accessible_and_correct(&buf[..], true, true).unwrap();
1964     }
1965 }
1966 
1967 #[cfg(test)]
1968 mod generated_code_asserts {
1969     extern crate flatbuffers;
1970 
1971     use super::my_game;
1972 
1973     #[test]
1974     #[should_panic]
monster_builder_fails_when_name_is_missing()1975     fn monster_builder_fails_when_name_is_missing() {
1976         let b = &mut flatbuffers::FlatBufferBuilder::new();
1977         my_game::example::Monster::create(b, &my_game::example::MonsterArgs{..Default::default()});
1978     }
1979 }
1980 
1981 #[cfg(test)]
1982 mod generated_key_comparisons {
1983     extern crate flatbuffers;
1984 
1985     use super::my_game;
1986 
1987     #[test]
struct_ability_key_compare_less_than()1988     fn struct_ability_key_compare_less_than() {
1989         let a = my_game::example::Ability::new(1, 2);
1990         let b = my_game::example::Ability::new(2, 1);
1991         let c = my_game::example::Ability::new(3, 3);
1992 
1993         assert_eq!(a.key_compare_less_than(&a), false);
1994         assert_eq!(b.key_compare_less_than(&b), false);
1995         assert_eq!(c.key_compare_less_than(&c), false);
1996 
1997         assert_eq!(a.key_compare_less_than(&b), true);
1998         assert_eq!(a.key_compare_less_than(&c), true);
1999 
2000         assert_eq!(b.key_compare_less_than(&a), false);
2001         assert_eq!(b.key_compare_less_than(&c), true);
2002 
2003         assert_eq!(c.key_compare_less_than(&a), false);
2004         assert_eq!(c.key_compare_less_than(&b), false);
2005     }
2006 
2007     #[test]
struct_key_compare_with_value()2008     fn struct_key_compare_with_value() {
2009         let a = my_game::example::Ability::new(1, 2);
2010 
2011         assert_eq!(a.key_compare_with_value(0), ::core::cmp::Ordering::Greater);
2012         assert_eq!(a.key_compare_with_value(1), ::core::cmp::Ordering::Equal);
2013         assert_eq!(a.key_compare_with_value(2), ::core::cmp::Ordering::Less);
2014     }
2015 
2016     #[test]
struct_key_compare_less_than()2017     fn struct_key_compare_less_than() {
2018         let a = my_game::example::Ability::new(1, 2);
2019         let b = my_game::example::Ability::new(2, 1);
2020         let c = my_game::example::Ability::new(3, 3);
2021 
2022         assert_eq!(a.key_compare_less_than(&a), false);
2023         assert_eq!(b.key_compare_less_than(&b), false);
2024         assert_eq!(c.key_compare_less_than(&c), false);
2025 
2026         assert_eq!(a.key_compare_less_than(&b), true);
2027         assert_eq!(a.key_compare_less_than(&c), true);
2028 
2029         assert_eq!(b.key_compare_less_than(&a), false);
2030         assert_eq!(b.key_compare_less_than(&c), true);
2031 
2032         assert_eq!(c.key_compare_less_than(&a), false);
2033         assert_eq!(c.key_compare_less_than(&b), false);
2034     }
2035 
2036     #[test]
table_key_compare_with_value()2037     fn table_key_compare_with_value() {
2038         // setup
2039         let builder = &mut flatbuffers::FlatBufferBuilder::new();
2040         super::create_serialized_example_with_library_code(builder);
2041         let buf = builder.finished_data();
2042         let a = my_game::example::root_as_monster(buf).unwrap();
2043 
2044         // preconditions
2045         assert_eq!(a.name(), "MyMonster");
2046 
2047         assert_eq!(a.key_compare_with_value("AAA"), ::core::cmp::Ordering::Greater);
2048         assert_eq!(a.key_compare_with_value("MyMonster"), ::core::cmp::Ordering::Equal);
2049         assert_eq!(a.key_compare_with_value("ZZZ"), ::core::cmp::Ordering::Less);
2050     }
2051 
2052     #[test]
table_key_compare_less_than()2053     fn table_key_compare_less_than() {
2054         // setup
2055         let builder = &mut flatbuffers::FlatBufferBuilder::new();
2056         super::create_serialized_example_with_library_code(builder);
2057         let buf = builder.finished_data();
2058         let a = my_game::example::root_as_monster(buf).unwrap();
2059         let b = a.test_as_monster().unwrap();
2060 
2061         // preconditions
2062         assert_eq!(a.name(), "MyMonster");
2063         assert_eq!(b.name(), "Fred");
2064 
2065         assert_eq!(a.key_compare_less_than(&a), false);
2066         assert_eq!(a.key_compare_less_than(&b), false);
2067 
2068         assert_eq!(b.key_compare_less_than(&a), true);
2069         assert_eq!(b.key_compare_less_than(&b), false);
2070     }
2071 }
2072 
2073 #[cfg(test)]
2074 mod included_schema_generated_code {
2075 
2076     #[test]
2077     #[allow(unused_imports)]
namespace_test_mod_is_importable()2078     fn namespace_test_mod_is_importable() {
2079         use super::namespace_test_generated::{
2080             namespace_a,
2081             namespace_a::namespace_b,
2082             namespace_c,
2083         };
2084 
2085     }
2086 }
2087 
2088 #[cfg(test)]
2089 mod builder_asserts {
2090     extern crate flatbuffers;
2091 
2092     #[test]
2093     #[should_panic]
end_table_should_panic_when_not_in_table()2094     fn end_table_should_panic_when_not_in_table() {
2095         let mut b = flatbuffers::FlatBufferBuilder::new();
2096         b.end_table(flatbuffers::WIPOffset::new(0));
2097     }
2098 
2099     #[test]
2100     #[should_panic]
create_string_should_panic_when_in_table()2101     fn create_string_should_panic_when_in_table() {
2102         let mut b = flatbuffers::FlatBufferBuilder::new();
2103         b.start_table();
2104         b.create_string("foo");
2105     }
2106 
2107     #[test]
2108     #[should_panic]
create_byte_string_should_panic_when_in_table()2109     fn create_byte_string_should_panic_when_in_table() {
2110         let mut b = flatbuffers::FlatBufferBuilder::new();
2111         b.start_table();
2112         b.create_byte_string(b"foo");
2113     }
2114 
2115     #[test]
2116     #[should_panic]
push_struct_slot_should_panic_when_not_in_table()2117     fn push_struct_slot_should_panic_when_not_in_table() {
2118         #[derive(Copy, Clone, Debug, PartialEq)]
2119         #[repr(C, packed)]
2120         struct foo { }
2121         impl<'b> flatbuffers::Push for &'b foo {
2122             type Output = foo;
2123             fn push<'a>(&'a self, _dst: &'a mut [u8], _rest: &'a [u8]) { }
2124         }
2125         let mut b = flatbuffers::FlatBufferBuilder::new();
2126         b.push_slot_always(0, &foo{});
2127     }
2128 
2129     #[test]
2130     #[should_panic]
finished_bytes_should_panic_when_table_is_not_finished()2131     fn finished_bytes_should_panic_when_table_is_not_finished() {
2132         let mut b = flatbuffers::FlatBufferBuilder::new();
2133         b.start_table();
2134         b.finished_data();
2135     }
2136 
2137     #[test]
2138     #[should_panic]
required_panics_when_field_not_set()2139     fn required_panics_when_field_not_set() {
2140         let mut b = flatbuffers::FlatBufferBuilder::new();
2141         let start = b.start_table();
2142         let o = b.end_table(start);
2143         b.required(o, 4 /* byte offset to first field */, "test field");
2144     }
2145 }
2146 
2147 #[cfg(test)]
2148 mod follow_impls {
2149     extern crate flatbuffers;
2150     use flatbuffers::Follow;
2151     use flatbuffers::field_index_to_field_offset as fi2fo;
2152 
2153     use alloc::vec::Vec;
2154 
2155     // Define a test struct to use in a few tests. This replicates the work that the code generator
2156     // would normally do when defining a FlatBuffer struct. For reference, compare the following
2157     // `FooStruct` code with the code generated for the `Vec3` struct in
2158     // `../../monster_test/mod.rs`.
2159     use flatbuffers::EndianScalar;
2160     #[derive(Copy, Clone, Debug, PartialEq)]
2161     #[repr(C, packed)]
2162     struct FooStruct {
2163         a: i8,
2164         b: u8,
2165         c: i16,
2166     }
2167     impl FooStruct {
new(_a: i8, _b: u8, _c: i16) -> Self2168         fn new(_a: i8, _b: u8, _c: i16) -> Self {
2169             FooStruct {
2170                 a: _a.to_little_endian(),
2171                 b: _b.to_little_endian(),
2172                 c: _c.to_little_endian(),
2173             }
2174         }
2175     }
2176     impl flatbuffers::SafeSliceAccess for FooStruct {}
2177     impl<'a> flatbuffers::Follow<'a> for FooStruct {
2178         type Inner = &'a FooStruct;
2179         #[inline(always)]
follow(buf: &'a [u8], loc: usize) -> Self::Inner2180         fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
2181             <&'a FooStruct>::follow(buf, loc)
2182         }
2183     }
2184     impl<'a> flatbuffers::Follow<'a> for &'a FooStruct {
2185         type Inner = &'a FooStruct;
2186         #[inline(always)]
follow(buf: &'a [u8], loc: usize) -> Self::Inner2187         fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
2188             flatbuffers::follow_cast_ref::<FooStruct>(buf, loc)
2189         }
2190     }
2191 
2192     #[test]
to_u8()2193     fn to_u8() {
2194         let vec: Vec<u8> = vec![255, 3];
2195         let fs: flatbuffers::FollowStart<u8> = flatbuffers::FollowStart::new();
2196         assert_eq!(fs.self_follow(&vec[..], 1), 3);
2197     }
2198 
2199     #[test]
to_u16()2200     fn to_u16() {
2201         let vec: Vec<u8> = vec![255, 255, 3, 4];
2202         let fs: flatbuffers::FollowStart<u16> = flatbuffers::FollowStart::new();
2203         assert_eq!(fs.self_follow(&vec[..], 2), 1027);
2204     }
2205 
2206     #[test]
to_f32()2207     fn to_f32() {
2208         let vec: Vec<u8> = vec![255, 255, 255, 255, /* start of value */ 208, 15, 73, 64];
2209         let fs: flatbuffers::FollowStart<f32> = flatbuffers::FollowStart::new();
2210         assert_eq!(fs.self_follow(&vec[..], 4), 3.14159);
2211     }
2212 
2213     #[test]
to_string()2214     fn to_string() {
2215         let vec: Vec<u8> = vec![255,255,255,255, 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
2216         let off: flatbuffers::FollowStart<&str> = flatbuffers::FollowStart::new();
2217         assert_eq!(off.self_follow(&vec[..], 4), "foo");
2218     }
2219 
2220     #[test]
to_byte_slice()2221     fn to_byte_slice() {
2222         let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
2223         let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
2224         assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3, 4][..]);
2225     }
2226 
2227     #[test]
to_byte_vector()2228     fn to_byte_vector() {
2229         let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
2230         let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
2231         assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3, 4][..]);
2232     }
2233 
2234     #[test]
to_byte_string_zero_teriminated()2235     fn to_byte_string_zero_teriminated() {
2236         let vec: Vec<u8> = vec![255, 255, 255, 255, 3, 0, 0, 0, 1, 2, 3, 0];
2237         let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
2238         assert_eq!(off.self_follow(&vec[..], 4).safe_slice(), &[1, 2, 3][..]);
2239     }
2240 
2241     #[test]
to_vector_of_u16()2242     fn to_vector_of_u16() {
2243         let vec: Vec<u8> = vec![255, 255, 255, 255, 2, 0, 0, 0, 1, 2, 3, 4];
2244         let off: flatbuffers::FollowStart<flatbuffers::Vector<u16>> = flatbuffers::FollowStart::new();
2245         assert_eq!(off.self_follow(&vec[..], 4).len(), 2);
2246         assert_eq!(off.self_follow(&vec[..], 4).get(0), 513);
2247         assert_eq!(off.self_follow(&vec[..], 4).get(1), 1027);
2248     }
2249 
2250     #[test]
to_struct()2251     fn to_struct() {
2252         let vec: Vec<u8> = vec![255, 255, 255, 255, 1, 2, 3, 4];
2253         let off: flatbuffers::FollowStart<&FooStruct> = flatbuffers::FollowStart::new();
2254         assert_eq!(*off.self_follow(&vec[..], 4), FooStruct::new(1, 2, 1027));
2255     }
2256 
2257     #[test]
to_vector_of_offset_to_string_elements()2258     fn to_vector_of_offset_to_string_elements() {
2259         let buf: Vec<u8> = vec![/* vec len */ 1, 0, 0, 0, /* offset to string */ 4, 0, 0, 0, /* str length */ 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
2260         let s: flatbuffers::FollowStart<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>> = flatbuffers::FollowStart::new();
2261         assert_eq!(s.self_follow(&buf[..], 0).len(), 1);
2262         assert_eq!(s.self_follow(&buf[..], 0).get(0), "foo");
2263     }
2264 
2265     #[test]
to_slice_of_struct_elements()2266     fn to_slice_of_struct_elements() {
2267         let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
2268         let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
2269         assert_eq!(fs.self_follow(&buf[..], 0).safe_slice(), &vec![FooStruct::new(1, 2, 1027)][..]);
2270     }
2271 
2272     #[test]
to_vector_of_struct_elements()2273     fn to_vector_of_struct_elements() {
2274         let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
2275         let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
2276         assert_eq!(fs.self_follow(&buf[..], 0).len(), 1);
2277         assert_eq!(fs.self_follow(&buf[..], 0).get(0), &FooStruct::new(1, 2, 1027));
2278     }
2279 
2280     #[test]
to_root_to_empty_table()2281     fn to_root_to_empty_table() {
2282         let buf: Vec<u8> = vec![
2283             12, 0, 0, 0, // offset to root table
2284             // enter vtable
2285             4, 0, // vtable len
2286             0, 0, // inline size
2287             255, 255, 255, 255, // canary
2288             // enter table
2289             8, 0, 0, 0, // vtable location
2290         ];
2291         let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2292         assert_eq!(fs.self_follow(&buf[..], 0), flatbuffers::Table::new(&buf[..], 12));
2293     }
2294 
2295     #[test]
to_root_table_get_slot_scalar_u8()2296     fn to_root_table_get_slot_scalar_u8() {
2297         let buf: Vec<u8> = vec![
2298             14, 0, 0, 0, // offset to root table
2299             // enter vtable
2300             6, 0, // vtable len
2301             2, 0, // inline size
2302             5, 0, // value loc
2303             255, 255, 255, 255, // canary
2304             // enter table
2305             10, 0, 0, 0, // vtable location
2306             0, 99 // value (with padding)
2307         ];
2308         let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2309         let tab = fs.self_follow(&buf[..], 0);
2310         assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(99));
2311     }
2312 
2313     #[test]
to_root_to_table_get_slot_scalar_u8_default_via_vtable_len()2314     fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_len() {
2315         let buf: Vec<u8> = vec![
2316             12, 0, 0, 0, // offset to root table
2317             // enter vtable
2318             4, 0, // vtable len
2319             2, 0, // inline size
2320             255, 255, 255, 255, // canary
2321             // enter table
2322             8, 0, 0, 0, // vtable location
2323         ];
2324         let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2325         let tab = fs.self_follow(&buf[..], 0);
2326         assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
2327     }
2328 
2329     #[test]
to_root_to_table_get_slot_scalar_u8_default_via_vtable_zero()2330     fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_zero() {
2331         let buf: Vec<u8> = vec![
2332             14, 0, 0, 0, // offset to root table
2333             // enter vtable
2334             6, 0, // vtable len
2335             2, 0, // inline size
2336             0, 0, // zero means use the default value
2337             255, 255, 255, 255, // canary
2338             // enter table
2339             10, 0, 0, 0, // vtable location
2340         ];
2341         let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2342         let tab = fs.self_follow(&buf[..], 0);
2343         assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
2344     }
2345 
2346     #[test]
to_root_to_table_get_slot_string_multiple_types()2347     fn to_root_to_table_get_slot_string_multiple_types() {
2348         let buf: Vec<u8> = vec![
2349             14, 0, 0, 0, // offset to root table
2350             // enter vtable
2351             6, 0, // vtable len
2352             2, 0, // inline size
2353             4, 0, // value loc
2354             255, 255, 255, 255, // canary
2355             // enter table
2356             10, 0, 0, 0, // vtable location
2357             8, 0, 0, 0, // offset to string
2358             // leave table
2359             255, 255, 255, 255, // canary
2360             // enter string
2361             3, 0, 0, 0, 109, 111, 111, 0 // string length and contents
2362         ];
2363         let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
2364         assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), None), Some("moo"));
2365         let byte_vec = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap().safe_slice();
2366         assert_eq!(byte_vec, &vec![109, 111, 111][..]);
2367         let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap();
2368         assert_eq!(v.len(), 3);
2369         assert_eq!(v.get(0), 109);
2370         assert_eq!(v.get(1), 111);
2371         assert_eq!(v.get(2), 111);
2372     }
2373 
2374     #[test]
to_root_to_table_get_slot_string_multiple_types_default_via_vtable_len()2375     fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_len() {
2376         let buf: Vec<u8> = vec![
2377             12, 0, 0, 0, // offset to root table
2378             // enter vtable
2379             4, 0, // vtable len
2380             4, 0, // table inline len
2381             255, 255, 255, 255, // canary
2382             // enter table
2383             8, 0, 0, 0, // vtable location
2384         ];
2385         let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
2386         assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
2387         #[cfg(target_endian = "little")]
2388         {
2389             assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
2390         }
2391 
2392         let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
2393         let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
2394         let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
2395         assert_eq!(v.len(), 3);
2396         assert_eq!(v.get(0), 70);
2397         assert_eq!(v.get(1), 71);
2398         assert_eq!(v.get(2), 72);
2399     }
2400 
2401     #[test]
to_root_to_table_get_slot_string_multiple_types_default_via_vtable_zero()2402     fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_zero() {
2403         let buf: Vec<u8> = vec![
2404             14, 0, 0, 0, // offset to root table
2405             // enter vtable
2406             6, 0, // vtable len
2407             2, 0, // inline size
2408             0, 0, // value loc
2409             255, 255, 255, 255, // canary
2410             // enter table
2411             10, 0, 0, 0, // vtable location
2412         ];
2413         let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
2414         assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
2415         #[cfg(target_endian = "little")]
2416         {
2417             assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
2418         }
2419 
2420         let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
2421         let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
2422         let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
2423         assert_eq!(v.len(), 3);
2424         assert_eq!(v.get(0), 70);
2425         assert_eq!(v.get(1), 71);
2426         assert_eq!(v.get(2), 72);
2427     }
2428 }
2429 
2430 #[cfg(test)]
2431 mod push_impls {
2432     extern crate flatbuffers;
2433 
2434     use super::my_game;
2435 
check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8])2436     fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
2437         let got = b.unfinished_data();
2438         assert_eq!(want, got);
2439     }
2440 
2441     #[test]
push_u8()2442     fn push_u8() {
2443         let mut b = flatbuffers::FlatBufferBuilder::new();
2444         b.push(123u8);
2445         check(&b, &[123]);
2446     }
2447 
2448     #[test]
push_u64()2449     fn push_u64() {
2450         let mut b = flatbuffers::FlatBufferBuilder::new();
2451         b.push(0x12345678);
2452         check(&b, &[0x78, 0x56, 0x34, 0x12]);
2453     }
2454 
2455     #[test]
push_f64()2456     fn push_f64() {
2457         let mut b = flatbuffers::FlatBufferBuilder::new();
2458         b.push(3.14159265359f64);
2459         check(&b, &[234, 46, 68, 84, 251, 33, 9, 64]);
2460     }
2461 
2462     #[test]
push_generated_struct()2463     fn push_generated_struct() {
2464         let mut b = flatbuffers::FlatBufferBuilder::new();
2465         b.push(my_game::example::Test::new(10, 20));
2466         check(&b, &[10, 0, 20, 0]);
2467     }
2468 
2469     #[test]
push_u8_vector_with_offset_with_alignment()2470     fn push_u8_vector_with_offset_with_alignment() {
2471         let mut b = flatbuffers::FlatBufferBuilder::new();
2472         let off = b.create_vector(&[1u8, 2, 3, 4, 5, 6, 7, 8, 9][..]);
2473         b.push(off);
2474         check(&b, &[/* loc */ 4, 0, 0, 0, /* len */ 9, 0, 0, 0, /* val */ 1, 2, 3, 4, 5, 6, 7, 8, 9, /* padding */ 0, 0, 0]);
2475     }
2476 
2477     #[test]
push_u8_u16_alignment()2478     fn push_u8_u16_alignment() {
2479         let mut b = flatbuffers::FlatBufferBuilder::new();
2480         b.push(1u8);
2481         b.push(2u16);
2482         check(&b, &[2, 0, 0, 1]);
2483     }
2484 
2485     #[test]
push_u8_u32_alignment()2486     fn push_u8_u32_alignment() {
2487         let mut b = flatbuffers::FlatBufferBuilder::new();
2488         b.push(1u8);
2489         b.push(2u32);
2490         check(&b, &[2, 0, 0, 0, 0, 0, 0, 1]);
2491     }
2492 
2493     #[test]
push_u8_u64_alignment()2494     fn push_u8_u64_alignment() {
2495         let mut b = flatbuffers::FlatBufferBuilder::new();
2496         b.push(1u8);
2497         b.push(2u64);
2498         check(&b, &[2, 0, 0, 0,
2499                     0, 0, 0, 0,
2500                     0, 0, 0, 0,
2501                     0, 0, 0, 1]);
2502     }
2503 }
2504 
2505 #[cfg(test)]
2506 mod vtable_deduplication {
2507     extern crate flatbuffers;
2508     use flatbuffers::field_index_to_field_offset as fi2fo;
2509 
check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8])2510     fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
2511         let got = b.unfinished_data();
2512         assert_eq!(want, got);
2513     }
2514 
2515     #[test]
one_empty_table()2516     fn one_empty_table() {
2517         let mut b = flatbuffers::FlatBufferBuilder::new();
2518         let start0 = b.start_table();
2519         b.end_table(start0);
2520         check(&b, &[
2521               4, 0, // vtable size in bytes
2522               4, 0, // object inline data in bytes
2523 
2524               4, 0, 0, 0, // backwards offset to vtable
2525         ]);
2526     }
2527 
2528     #[test]
two_empty_tables_are_deduplicated()2529     fn two_empty_tables_are_deduplicated() {
2530         let mut b = flatbuffers::FlatBufferBuilder::new();
2531         let start0 = b.start_table();
2532         b.end_table(start0);
2533         let start1 = b.start_table();
2534         b.end_table(start1);
2535         check(&b, &[
2536               252, 255, 255, 255, // forwards offset to vtable
2537 
2538               4, 0, // vtable size in bytes
2539               4, 0, // object inline data in bytes
2540 
2541               4, 0, 0, 0, // backwards offset to vtable
2542         ]);
2543     }
2544 
2545     #[test]
two_tables_with_two_conveniently_sized_inline_elements_are_deduplicated()2546     fn two_tables_with_two_conveniently_sized_inline_elements_are_deduplicated() {
2547         let mut b = flatbuffers::FlatBufferBuilder::new();
2548         let start0 = b.start_table();
2549         b.push_slot::<u64>(fi2fo(0), 100, 0);
2550         b.push_slot::<u32>(fi2fo(1), 101, 0);
2551         b.end_table(start0);
2552         let start1 = b.start_table();
2553         b.push_slot::<u64>(fi2fo(0), 200, 0);
2554         b.push_slot::<u32>(fi2fo(1), 201, 0);
2555         b.end_table(start1);
2556         check(&b, &[
2557               240, 255, 255, 255, // forwards offset to vtable
2558 
2559               201, 0, 0, 0, // value #1
2560               200, 0, 0, 0, 0, 0, 0, 0, // value #0
2561 
2562               8, 0, // vtable size in bytes
2563               16, 0, // object inline data in bytes
2564               8, 0, // offset in object for value #0
2565               4, 0, // offset in object for value #1
2566 
2567               8, 0, 0, 0, // backwards offset to vtable
2568               101, 0, 0, 0, // value #1
2569               100, 0, 0, 0, 0, 0, 0, 0 // value #0
2570         ]);
2571     }
2572 
2573     #[cfg(not(miri))]  // slow.
2574     #[test]
many_identical_tables_use_few_vtables()2575     fn many_identical_tables_use_few_vtables() {
2576         let mut b = flatbuffers::FlatBufferBuilder::new();
2577         for _ in 0..1000 {
2578             let start = b.start_table();
2579             b.push_slot::<u8>(fi2fo(0), 100, 0);
2580             b.push_slot::<u32>(fi2fo(1), 101, 0);
2581             b.end_table(start);
2582         }
2583         assert!(b.num_written_vtables() <= 10);
2584     }
2585 }
2586 
2587 #[cfg(test)]
2588 mod byte_layouts {
2589     extern crate flatbuffers;
2590     use flatbuffers::field_index_to_field_offset as fi2fo;
2591 
check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8])2592     fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
2593         let got = b.unfinished_data();
2594         assert_eq!(want, got);
2595     }
2596 
2597     #[test]
layout_01_basic_numbers()2598     fn layout_01_basic_numbers() {
2599         let mut b = flatbuffers::FlatBufferBuilder::new();
2600         b.push(true);
2601         check(&b, &[1]);
2602         b.push(-127i8);
2603         check(&b, &[129, 1]);
2604         b.push(255u8);
2605         check(&b, &[255, 129, 1]);
2606         b.push(-32222i16);
2607         check(&b, &[0x22, 0x82, 0, 255, 129, 1]); // first pad
2608         b.push(0xFEEEu16);
2609         check(&b, &[0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]); // no pad this time
2610         b.push(-53687092i32);
2611         check(&b, &[204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
2612         b.push(0x98765432u32);
2613         check(&b, &[0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
2614     }
2615 
2616     #[test]
layout_01b_bigger_numbers()2617     fn layout_01b_bigger_numbers() {
2618         let mut b = flatbuffers::FlatBufferBuilder::new();
2619         b.push(0x1122334455667788u64);
2620         check(&b, &[0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]);
2621     }
2622 
2623     #[test]
layout_02_1xbyte_vector()2624     fn layout_02_1xbyte_vector() {
2625         let mut b = flatbuffers::FlatBufferBuilder::new();
2626         check(&b, &[]);
2627         b.start_vector::<u8>(1);
2628         check(&b, &[0, 0, 0]); // align to 4bytes
2629         b.push(1u8);
2630         check(&b, &[1, 0, 0, 0]);
2631         b.end_vector::<u8>(1);
2632         check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
2633     }
2634 
2635     #[test]
layout_03_2xbyte_vector()2636     fn layout_03_2xbyte_vector() {
2637         let mut b = flatbuffers::FlatBufferBuilder::new();
2638         b.start_vector::<u8>(2);
2639         check(&b, &[0, 0]); // align to 4bytes
2640         b.push(1u8);
2641         check(&b, &[1, 0, 0]);
2642         b.push(2u8);
2643         check(&b, &[2, 1, 0, 0]);
2644         b.end_vector::<u8>(2);
2645         check(&b, &[2, 0, 0, 0, 2, 1, 0, 0]); // padding
2646     }
2647 
2648     #[test]
layout_03b_11xbyte_vector_matches_builder_size()2649     fn layout_03b_11xbyte_vector_matches_builder_size() {
2650         let mut b = flatbuffers::FlatBufferBuilder::with_capacity(12);
2651         b.start_vector::<u8>(8);
2652 
2653         let mut gold = vec![0u8; 0];
2654         check(&b, &gold[..]);
2655 
2656         for i in 1u8..=8 {
2657             b.push(i);
2658             gold.insert(0, i);
2659             check(&b, &gold[..]);
2660         }
2661         b.end_vector::<u8>(8);
2662         let want = vec![8u8, 0, 0, 0,  8, 7, 6, 5, 4, 3, 2, 1];
2663         check(&b, &want[..]);
2664     }
2665     #[test]
layout_04_1xuint16_vector()2666     fn layout_04_1xuint16_vector() {
2667         let mut b = flatbuffers::FlatBufferBuilder::new();
2668         b.start_vector::<u16>(1);
2669         check(&b, &[0, 0]); // align to 4bytes
2670         b.push(1u16);
2671         check(&b, &[1, 0, 0, 0]);
2672         b.end_vector::<u16>(1);
2673         check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
2674     }
2675 
2676     #[test]
layout_05_2xuint16_vector()2677     fn layout_05_2xuint16_vector() {
2678         let mut b = flatbuffers::FlatBufferBuilder::new();
2679         let _off = b.start_vector::<u16>(2);
2680         check(&b, &[]); // align to 4bytes
2681         b.push(0xABCDu16);
2682         check(&b, &[0xCD, 0xAB]);
2683         b.push(0xDCBAu16);
2684         check(&b, &[0xBA, 0xDC, 0xCD, 0xAB]);
2685         b.end_vector::<u16>(2);
2686         check(&b, &[2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB]);
2687     }
2688 
2689     #[test]
layout_06_create_string()2690     fn layout_06_create_string() {
2691         let mut b = flatbuffers::FlatBufferBuilder::new();
2692         let off0 = b.create_string("foo");
2693         assert_eq!(8, off0.value());
2694         check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
2695         let off1 = b.create_string("moop");
2696         assert_eq!(20, off1.value());
2697         check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
2698                     \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
2699     }
2700 
2701     #[test]
layout_06b_create_string_unicode()2702     fn layout_06b_create_string_unicode() {
2703         let mut b = flatbuffers::FlatBufferBuilder::new();
2704         // These characters are chinese from blog.golang.org/strings
2705         // We use escape codes here so that editors without unicode support
2706         // aren't bothered:
2707         let uni_str = "\u{65e5}\u{672c}\u{8a9e}";
2708         let off0 = b.create_string(uni_str);
2709         assert_eq!(16, off0.value());
2710         check(&b, &[9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
2711                     0, 0]);
2712     }
2713 
2714     #[test]
layout_06c_create_byte_string()2715     fn layout_06c_create_byte_string() {
2716         let mut b = flatbuffers::FlatBufferBuilder::new();
2717         let off0 = b.create_byte_string(b"foo");
2718         assert_eq!(8, off0.value());
2719         check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
2720         let off1 = b.create_byte_string(b"moop");
2721         assert_eq!(20, off1.value());
2722         check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
2723                     \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
2724     }
2725 
2726     #[test]
layout_07_empty_vtable()2727     fn layout_07_empty_vtable() {
2728         let mut b = flatbuffers::FlatBufferBuilder::new();
2729         let off0 = b.start_table();
2730         check(&b, &[]);
2731         b.end_table(off0);
2732         check(&b, &[4, 0, // vtable length
2733                     4, 0, // length of table including vtable offset
2734                     4, 0, 0, 0]); // offset for start of vtable
2735     }
2736 
2737     #[test]
layout_08_vtable_with_one_true_bool()2738     fn layout_08_vtable_with_one_true_bool() {
2739         let mut b = flatbuffers::FlatBufferBuilder::new();
2740         check(&b, &[]);
2741         let off0 = b.start_table();
2742         assert_eq!(0, off0.value());
2743         check(&b, &[]);
2744         b.push_slot(fi2fo(0), true, false);
2745         check(&b, &[1]);
2746         let off1 = b.end_table(off0);
2747         assert_eq!(8, off1.value());
2748         check(&b, &[
2749               6, 0, // vtable bytes
2750               8, 0, // length of object including vtable offset
2751               7, 0, // start of bool value
2752               6, 0, 0, 0, // offset for start of vtable (int32)
2753               0, 0, 0, // padded to 4 bytes
2754               1, // bool value
2755         ]);
2756     }
2757 
2758     #[test]
layout_09_vtable_with_one_default_bool()2759     fn layout_09_vtable_with_one_default_bool() {
2760         let mut b = flatbuffers::FlatBufferBuilder::new();
2761         check(&b, &[]);
2762         let off = b.start_table();
2763         check(&b, &[]);
2764         b.push_slot(fi2fo(0), false, false);
2765         b.end_table(off);
2766         check(&b, &[
2767              4, 0, // vtable bytes
2768              4, 0, // end of object from here
2769              // entry 1 is zero and not stored.
2770              4, 0, 0, 0, // offset for start of vtable (int32)
2771         ]);
2772     }
2773 
2774     #[test]
layout_09b_vtable_with_one_default_bool_force_defaults()2775     fn layout_09b_vtable_with_one_default_bool_force_defaults() {
2776         let mut b = flatbuffers::FlatBufferBuilder::new();
2777         check(&b, &[]);
2778         let off = b.start_table();
2779         check(&b, &[]);
2780         b.force_defaults(true);
2781         b.push_slot(fi2fo(0), false, false);
2782         b.end_table(off);
2783         check(&b, &[
2784             6, 0, // vtable bytes
2785             8, 0, // length of object including vtable offset
2786             7, 0, // start of bool value
2787             6, 0, 0, 0, // offset for start of vtable (int32)
2788             0, 0, 0, // padded to 4 bytes
2789             0, // bool value
2790       ]);
2791     }
2792 
2793     #[test]
layout_10_vtable_with_one_int16()2794     fn layout_10_vtable_with_one_int16() {
2795         let mut b = flatbuffers::FlatBufferBuilder::new();
2796         check(&b, &[]);
2797         let off = b.start_table();
2798         b.push_slot(fi2fo(0), 0x789Ai16, 0);
2799         b.end_table(off);
2800         check(&b, &[
2801               6, 0, // vtable bytes
2802               8, 0, // end of object from here
2803               6, 0, // offset to value
2804               6, 0, 0, 0, // offset for start of vtable (int32)
2805               0, 0, // padding to 4 bytes
2806               0x9A, 0x78,
2807         ]);
2808     }
2809 
2810     #[test]
layout_11_vtable_with_two_int16()2811     fn layout_11_vtable_with_two_int16() {
2812         let mut b = flatbuffers::FlatBufferBuilder::new();
2813         let off = b.start_table();
2814         b.push_slot(fi2fo(0), 0x3456i16, 0);
2815         b.push_slot(fi2fo(1), 0x789Ai16, 0);
2816         b.end_table(off);
2817         check(&b, &[
2818               8, 0, // vtable bytes
2819               8, 0, // end of object from here
2820               6, 0, // offset to value 0
2821               4, 0, // offset to value 1
2822               8, 0, 0, 0, // offset for start of vtable (int32)
2823               0x9A, 0x78, // value 1
2824               0x56, 0x34, // value 0
2825         ]);
2826     }
2827 
2828     #[test]
layout_12_vtable_with_int16_and_bool()2829     fn layout_12_vtable_with_int16_and_bool() {
2830         let mut b = flatbuffers::FlatBufferBuilder::new();
2831         let off = b.start_table();
2832         b.push_slot(fi2fo(0), 0x3456i16, 0);
2833         b.push_slot(fi2fo(1), true, false);
2834         b.end_table(off);
2835         check(&b, &[
2836             8, 0, // vtable bytes
2837             8, 0, // end of object from here
2838             6, 0, // offset to value 0
2839             5, 0, // offset to value 1
2840             8, 0, 0, 0, // offset for start of vtable (int32)
2841             0,          // padding
2842             1,          // value 1
2843             0x56, 0x34, // value 0
2844         ]);
2845     }
2846 
2847     #[test]
layout_12b_vtable_with_empty_vector()2848     fn layout_12b_vtable_with_empty_vector() {
2849         let mut b = flatbuffers::FlatBufferBuilder::new();
2850         b.start_vector::<u8>(0);
2851         let vecend = b.end_vector::<u8>(0);
2852         let off = b.start_table();
2853         b.push_slot_always(fi2fo(0), vecend);
2854         b.end_table(off);
2855         check(&b, &[
2856               6, 0, // vtable bytes
2857               8, 0,
2858               4, 0, // offset to vector offset
2859               6, 0, 0, 0, // offset for start of vtable (int32)
2860               4, 0, 0, 0,
2861               0, 0, 0, 0, // length of vector (not in struct)
2862         ]);
2863     }
2864 
2865     #[test]
layout_12c_vtable_with_empty_vector_of_byte_and_some_scalars()2866     fn layout_12c_vtable_with_empty_vector_of_byte_and_some_scalars() {
2867         let mut b = flatbuffers::FlatBufferBuilder::new();
2868         b.start_vector::<u8>(0);
2869         let vecend = b.end_vector::<u8>(0);
2870         let off = b.start_table();
2871         b.push_slot::<i16>(fi2fo(0), 55i16, 0);
2872         b.push_slot_always::<flatbuffers::WIPOffset<_>>(fi2fo(1), vecend);
2873         b.end_table(off);
2874         check(&b, &[
2875               8, 0, // vtable bytes
2876               12, 0,
2877               10, 0, // offset to value 0
2878               4, 0, // offset to vector offset
2879               8, 0, 0, 0, // vtable loc
2880               8, 0, 0, 0, // value 1
2881               0, 0, 55, 0, // value 0
2882 
2883               0, 0, 0, 0, // length of vector (not in struct)
2884         ]);
2885     }
2886     #[test]
layout_13_vtable_with_1_int16_and_2_vector_of_i16()2887     fn layout_13_vtable_with_1_int16_and_2_vector_of_i16() {
2888         let mut b = flatbuffers::FlatBufferBuilder::new();
2889         b.start_vector::<i16>(2);
2890         b.push(0x1234i16);
2891         b.push(0x5678i16);
2892         let vecend = b.end_vector::<i16>(2);
2893         let off = b.start_table();
2894         b.push_slot_always(fi2fo(1), vecend);
2895         b.push_slot(fi2fo(0), 55i16, 0);
2896         b.end_table(off);
2897         check(&b, &[
2898               8, 0, // vtable bytes
2899               12, 0, // length of object
2900               6, 0, // start of value 0 from end of vtable
2901               8, 0, // start of value 1 from end of buffer
2902               8, 0, 0, 0, // offset for start of vtable (int32)
2903               0, 0, // padding
2904               55, 0, // value 0
2905               4, 0, 0, 0, // vector position from here
2906               2, 0, 0, 0, // length of vector (uint32)
2907               0x78, 0x56, // vector value 1
2908               0x34, 0x12, // vector value 0
2909         ]);
2910     }
2911     #[test]
layout_14_vtable_with_1_struct_of_int8_and_int16_and_int32()2912     fn layout_14_vtable_with_1_struct_of_int8_and_int16_and_int32() {
2913         #[derive(Copy, Clone, Debug, Eq, PartialEq)]
2914         #[repr(C, packed)]
2915         struct foo {
2916             a: i32,
2917             _pad0: [u8; 2],
2918             b: i16,
2919             _pad1: [u8; 3],
2920             c: i8,
2921             _pad2: [u8; 4],
2922         }
2923         assert_eq!(::core::mem::size_of::<foo>(), 16);
2924         impl<'b> flatbuffers::Push for &'b foo {
2925             type Output = foo;
2926             fn push<'a>(&'a self, dst: &'a mut [u8], _rest: &'a [u8]) {
2927                 let src = unsafe {
2928                     ::core::slice::from_raw_parts(*self as *const foo as *const u8, ::core::mem::size_of::<foo>())
2929                 };
2930                 dst.copy_from_slice(src);
2931             }
2932         }
2933 
2934         let mut b = flatbuffers::FlatBufferBuilder::new();
2935         let off = b.start_table();
2936         let x = foo{a: 0x12345678i32.to_le(), _pad0: [0,0], b: 0x1234i16.to_le(), _pad1: [0, 0, 0], c: 0x12i8.to_le(), _pad2: [0, 0, 0, 0]};
2937         b.push_slot_always(fi2fo(0), &x);
2938         b.end_table(off);
2939         check(&b, &[
2940               6, 0, // vtable bytes
2941               20, 0, // end of object from here
2942               4, 0, // start of struct from here
2943               6, 0, 0, 0, // offset for start of vtable (int32)
2944 
2945               0x78, 0x56, 0x34, 0x12, // value a
2946               0, 0, // padding
2947               0x34, 0x12, // value b
2948               0, 0, 0, // padding
2949               0x12, // value c
2950               0, 0, 0, 0, // padding
2951         ]);
2952     }
2953     #[test]
layout_15_vtable_with_1_vector_of_4_int8()2954     fn layout_15_vtable_with_1_vector_of_4_int8() {
2955         let mut b = flatbuffers::FlatBufferBuilder::new();
2956         b.start_vector::<i8>(4);
2957         b.push(33i8);
2958         b.push(44i8);
2959         b.push(55i8);
2960         b.push(66i8);
2961         let vecend = b.end_vector::<i8>(4);
2962         let off = b.start_table();
2963         b.push_slot_always(fi2fo(0), vecend);
2964         b.end_table(off);
2965         check(&b, &[
2966               6, 0, // vtable bytes
2967               8, 0,
2968               4, 0, // offset of vector offset
2969               6, 0, 0, 0, // offset for start of vtable (int32)
2970               4, 0, 0, 0, // vector start offset
2971 
2972               4, 0, 0, 0, // vector length
2973               66, // vector value 1,1
2974               55, // vector value 1,0
2975               44, // vector value 0,1
2976               33, // vector value 0,0
2977         ]);
2978     }
2979 
2980     #[test]
layout_16_table_with_some_elements()2981     fn layout_16_table_with_some_elements() {
2982         let mut b = flatbuffers::FlatBufferBuilder::new();
2983         let off = b.start_table();
2984         b.push_slot(fi2fo(0), 33i8, 0);
2985         b.push_slot(fi2fo(1), 66i16, 0);
2986         let off2 = b.end_table(off);
2987         b.finish_minimal(off2);
2988 
2989         check(&b, &[
2990               12, 0, 0, 0, // root of table: points to vtable offset
2991 
2992               8, 0, // vtable bytes
2993               8, 0, // end of object from here
2994               7, 0, // start of value 0
2995               4, 0, // start of value 1
2996 
2997               8, 0, 0, 0, // offset for start of vtable (int32)
2998 
2999               66, 0, // value 1
3000               0,  // padding
3001               33, // value 0
3002         ]);
3003     }
3004 
3005     #[test]
layout_17_one_unfinished_table_and_one_finished_table()3006     fn layout_17_one_unfinished_table_and_one_finished_table() {
3007         let mut b = flatbuffers::FlatBufferBuilder::new();
3008         {
3009             let off = b.start_table();
3010             b.push_slot(fi2fo(0), 33i8, 0);
3011             b.push_slot(fi2fo(1), 44i8, 0);
3012             b.end_table(off);
3013         }
3014 
3015         {
3016             let off = b.start_table();
3017             b.push_slot(fi2fo(0), 55i8, 0);
3018             b.push_slot(fi2fo(1), 66i8, 0);
3019             b.push_slot(fi2fo(2), 77i8, 0);
3020             let off2 = b.end_table(off);
3021             b.finish_minimal(off2);
3022         }
3023 
3024         check(&b, &[
3025               16, 0, 0, 0, // root of table: points to object
3026               0, 0, // padding
3027 
3028               10, 0, // vtable bytes
3029               8, 0, // size of object
3030               7, 0, // start of value 0
3031               6, 0, // start of value 1
3032               5, 0, // start of value 2
3033               10, 0, 0, 0, // offset for start of vtable (int32)
3034               0,  // padding
3035               77, // value 2
3036               66, // value 1
3037               55, // value 0
3038 
3039               //12, 0, 0, 0, // root of table: points to object
3040 
3041               8, 0, // vtable bytes
3042               8, 0, // size of object
3043               7, 0, // start of value 0
3044               6, 0, // start of value 1
3045               8, 0, 0, 0, // offset for start of vtable (int32)
3046               0, 0, // padding
3047               44, // value 1
3048               33, // value 0
3049               ]);
3050     }
3051 
3052     #[test]
layout_18_a_bunch_of_bools()3053     fn layout_18_a_bunch_of_bools() {
3054         let mut b = flatbuffers::FlatBufferBuilder::new();
3055         let off = b.start_table();
3056         b.push_slot(fi2fo(0), true, false);
3057         b.push_slot(fi2fo(1), true, false);
3058         b.push_slot(fi2fo(2), true, false);
3059         b.push_slot(fi2fo(3), true, false);
3060         b.push_slot(fi2fo(4), true, false);
3061         b.push_slot(fi2fo(5), true, false);
3062         b.push_slot(fi2fo(6), true, false);
3063         b.push_slot(fi2fo(7), true, false);
3064         let off2 = b.end_table(off);
3065         b.finish_minimal(off2);
3066 
3067         check(&b, &[
3068               24, 0, 0, 0, // root of table: points to vtable offset
3069 
3070               20, 0, // vtable bytes
3071               12, 0, // size of object
3072               11, 0, // start of value 0
3073               10, 0, // start of value 1
3074               9, 0, // start of value 2
3075               8, 0, // start of value 3
3076               7, 0, // start of value 4
3077               6, 0, // start of value 5
3078               5, 0, // start of value 6
3079               4, 0, // start of value 7
3080               20, 0, 0, 0, // vtable offset
3081 
3082               1, // value 7
3083               1, // value 6
3084               1, // value 5
3085               1, // value 4
3086               1, // value 3
3087               1, // value 2
3088               1, // value 1
3089               1, // value 0
3090               ]);
3091     }
3092 
3093     #[test]
layout_19_three_bools()3094     fn layout_19_three_bools() {
3095         let mut b = flatbuffers::FlatBufferBuilder::new();
3096         let off = b.start_table();
3097         b.push_slot(fi2fo(0), true, false);
3098         b.push_slot(fi2fo(1), true, false);
3099         b.push_slot(fi2fo(2), true, false);
3100         let off2 = b.end_table(off);
3101         b.finish_minimal(off2);
3102 
3103         check(&b, &[
3104               16, 0, 0, 0, // root of table: points to vtable offset
3105 
3106               0, 0, // padding
3107 
3108               10, 0, // vtable bytes
3109               8, 0, // size of object
3110               7, 0, // start of value 0
3111               6, 0, // start of value 1
3112               5, 0, // start of value 2
3113               10, 0, 0, 0, // vtable offset from here
3114 
3115               0, // padding
3116               1, // value 2
3117               1, // value 1
3118               1, // value 0
3119         ]);
3120     }
3121 
3122     #[test]
layout_20_some_floats()3123     fn layout_20_some_floats() {
3124         let mut b = flatbuffers::FlatBufferBuilder::new();
3125         let off = b.start_table();
3126         b.push_slot(fi2fo(0), 1.0f32, 0.0);
3127         b.end_table(off);
3128 
3129         check(&b, &[
3130               6, 0, // vtable bytes
3131               8, 0, // size of object
3132               4, 0, // start of value 0
3133               6, 0, 0, 0, // vtable offset
3134 
3135               0, 0, 128, 63, // value 0
3136         ]);
3137     }
3138 
3139     #[test]
layout_21_vtable_defaults()3140     fn layout_21_vtable_defaults() {
3141         let mut b = flatbuffers::FlatBufferBuilder::new();
3142         let off = b.start_table();
3143         b.push_slot::<i8>(fi2fo(0), 1, 1);
3144         b.push_slot::<i8>(fi2fo(1), 3, 2);
3145         b.push_slot::<i8>(fi2fo(2), 3, 3);
3146         b.end_table(off);
3147         check(&b, &[
3148               8, 0, // vtable size in bytes
3149               8, 0, // object inline data in bytes
3150               0, 0, // entry 1/3: 0 => default
3151               7, 0, // entry 2/3: 7 => table start + 7 bytes
3152               // entry 3/3: not present => default
3153               8, 0, 0, 0,
3154               0, 0, 0,
3155               3,
3156         ]);
3157     }
3158 
3159     #[test]
layout_22_root()3160     fn layout_22_root() {
3161         let mut b = flatbuffers::FlatBufferBuilder::new();
3162         let off = b.start_table();
3163         // skipped: b.push_slot_scalar::<i16>(0, 1, 1);
3164         b.push_slot::<i16>(fi2fo(1), 3, 2);
3165         b.push_slot::<i16>(fi2fo(2), 3, 3);
3166         let table_end = b.end_table(off);
3167         b.finish_minimal(table_end);
3168         check(&b, &[
3169               12, 0, 0, 0, // root
3170 
3171               8, 0, // vtable size in bytes
3172               8, 0, // object inline data in bytes
3173               0, 0, // entry 1/3: 0 => default
3174               6, 0, // entry 2/3: 6 => table start + 6 bytes
3175               // entry 3/3: not present => default
3176               8, 0, 0, 0, // size of table data in bytes
3177               0, 0, // padding
3178               3, 0, // value 2/3
3179         ]);
3180     }
3181     #[test]
layout_23_varied_slots_and_root()3182     fn layout_23_varied_slots_and_root() {
3183         let mut b = flatbuffers::FlatBufferBuilder::new();
3184         let off = b.start_table();
3185         b.push_slot::<i16>(fi2fo(0), 1, 0);
3186         b.push_slot::<u8>(fi2fo(1), 2, 0);
3187         b.push_slot::<f32>(fi2fo(2), 3.0, 0.0);
3188         let table_end = b.end_table(off);
3189         b.finish_minimal(table_end);
3190         check(&b, &[
3191               16, 0, 0, 0, // root
3192               0, 0, // padding
3193               10, 0, // vtable bytes
3194               12, 0, // object inline data size
3195               10, 0, // offset to value #1 (i16)
3196               9, 0, // offset to value #2 (u8)
3197               4, 0, // offset to value #3 (f32)
3198               10, 0, // offset to vtable
3199               0, 0, // padding
3200               0, 0, 64, 64, // value #3 => 3.0 (float32)
3201               0, 2, // value #1 => 2 (u8)
3202               1, 0, // value #0 => 1 (int16)
3203         ]);
3204     }
3205 }
3206 
3207 #[cfg(test)]
3208 mod copy_clone_traits {
3209 
3210     use alloc::vec::Vec;
3211 
3212     #[test]
follow_types_implement_copy_and_clone()3213     fn follow_types_implement_copy_and_clone() {
3214         static_assertions::assert_impl_all!(flatbuffers::WIPOffset<u32>: Copy, Clone);
3215         static_assertions::assert_impl_all!(flatbuffers::WIPOffset<Vec<u32>>: Copy, Clone);
3216 
3217         static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<u32>: Copy, Clone);
3218         static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<Vec<u32>>: Copy, Clone);
3219 
3220         static_assertions::assert_impl_all!(flatbuffers::Vector<'static, u32>: Copy, Clone);
3221         static_assertions::assert_impl_all!(flatbuffers::Vector<'static, Vec<u32>>: Copy, Clone);
3222     }
3223 }
3224 
3225 #[cfg(test)]
3226 mod fully_qualified_name {
3227     #[test]
fully_qualified_name_generated()3228     fn fully_qualified_name_generated() {
3229         assert!(check_eq!(super::my_game::example::Monster::get_fully_qualified_name(), "MyGame.Example.Monster").is_ok());
3230         assert!(check_eq!(super::my_game::example_2::Monster::get_fully_qualified_name(), "MyGame.Example2.Monster").is_ok());
3231 
3232         assert!(check_eq!(super::my_game::example::Vec3::get_fully_qualified_name(), "MyGame.Example.Vec3").is_ok());
3233         assert!(check_eq!(super::my_game::example::Ability::get_fully_qualified_name(), "MyGame.Example.Ability").is_ok());
3234     }
3235 }
3236 
3237 // this is not technically a test, but we want to always keep this generated
3238 // file up-to-date, and the simplest way to do that is to make sure that when
3239 // tests are run, the file is generated.
3240 #[cfg(not(feature = "no_std"))]
3241 #[test]
write_example_wire_data_to_file()3242 fn write_example_wire_data_to_file() {
3243     let b = &mut flatbuffers::FlatBufferBuilder::new();
3244     create_serialized_example_with_generated_code(b);
3245 
3246     use ::std::io::Write;
3247     let mut f = std::fs::File::create("../monsterdata_rust_wire.mon").unwrap();
3248     f.write_all(b.finished_data()).unwrap();
3249 }
3250 
3251 #[cfg(not(feature = "no_std"))]
load_file(filename: &str) -> Result<Vec<u8>, std::io::Error>3252 fn load_file(filename: &str) -> Result<Vec<u8>, std::io::Error> {
3253     use std::io::Read;
3254     let mut f = std::fs::File::open(filename)?;
3255     let mut buf = Vec::new();
3256     f.read_to_end(&mut buf)?;
3257     Ok(buf)
3258 }
3259 
3260 #[test]
test_shared_strings()3261 fn test_shared_strings() {
3262     let mut builder = flatbuffers::FlatBufferBuilder::new();
3263     let offset1 = builder.create_shared_string("welcome to flatbuffers!!");
3264     let offset2 = builder.create_shared_string("welcome");
3265     let offset3 = builder.create_shared_string("welcome to flatbuffers!!");
3266     assert_ne!(offset2.value(), offset3.value());
3267     assert_eq!(offset1.value(), offset3.value());
3268     builder.reset();
3269     let offset4 = builder.create_shared_string("welcome");
3270     let offset5 = builder.create_shared_string("welcome to flatbuffers!!");
3271     assert_ne!(offset2.value(), offset4.value());
3272     assert_ne!(offset5.value(), offset1.value());
3273     builder.reset();
3274 
3275     // Checks if the shared string function would always work with
3276     // an object in between the writes
3277     let name = builder.create_shared_string("foo");
3278     let enemy = my_game::example::Monster::create(&mut builder, &my_game::example::MonsterArgs {
3279         name: Some(name),
3280         ..Default::default()
3281     });
3282     let secondary_name = builder.create_shared_string("foo");
3283     assert_eq!(name.value(), secondary_name.value());
3284 
3285     // Builds a new monster object and embeds enemy into it so we can verify
3286     // that shared strings are working.
3287     let args = my_game::example::MonsterArgs {
3288         name: Some(secondary_name),
3289         enemy: Some(enemy),
3290         testarrayofstring: Some(builder.create_vector(&[name, secondary_name])),
3291         ..Default::default()
3292     };
3293     // Building secondary monster
3294     let main_monster = my_game::example::Monster::create(&mut builder, &args);
3295     builder.finish(main_monster, None);
3296     let monster = my_game::example::root_as_monster(builder.finished_data()).unwrap();
3297 
3298     // Checks if the embedded object (Enemy) name is foo
3299     assert_eq!(monster.enemy().unwrap().name(), "foo");
3300     let string_vector = monster.testarrayofstring().unwrap();
3301     // Check if the vector will have the same string
3302     assert_eq!(string_vector.get(0), "foo");
3303     assert_eq!(string_vector.get(1), "foo");
3304 }
3305 
3306 }
3307