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