• 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: Green, test3: Test { a: 5, b: 6 } }), \
1771             mana: 150, hp: 80, name: \"MyMonster\", \
1772             inventory: Some([0, 1, 2, 3, 4]), color: Blue, test_type: Monster, \
1773             test: Monster { pos: None, mana: 150, hp: 100, name: \"Fred\", \
1774             inventory: None, color: Blue, test_type: NONE, test: None, \
1775             test4: None, testarrayofstring: None, testarrayoftables: None, \
1776             enemy: None, testnestedflatbuffer: None, testempty: None, \
1777             testbool: false, testhashs32_fnv1: 0, testhashu32_fnv1: 0, \
1778             testhashs64_fnv1: 0, testhashu64_fnv1: 0, testhashs32_fnv1a: 0, \
1779             testhashu32_fnv1a: 0, testhashs64_fnv1a: 0, testhashu64_fnv1a: 0, \
1780             testarrayofbools: None, testf: 3.14159, testf2: 3.00000, testf3: 0.00000, \
1781             testarrayofstring2: None, testarrayofsortedstruct: None, flex: None, \
1782             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: None, \
1791             native_inline: None, long_enum_non_enum_default: (empty), \
1792             long_enum_normal_default: LongOne, nan_default: NaN, inf_default: \
1793             inf, positive_inf_default: inf, infinity_default: inf, \
1794             positive_infinity_default: inf, negative_inf_default: -inf, \
1795             negative_infinity_default: -inf, double_inf_default: inf }, \
1796             test4: Some([Test { a: 10, b: 20 }, Test { a: 30, b: 40 }]), \
1797             testarrayofstring: Some([\"test1\", \"test2\"]), \
1798             testarrayoftables: None, enemy: None, testnestedflatbuffer: None, \
1799             testempty: None, testbool: false, testhashs32_fnv1: 0, \
1800             testhashu32_fnv1: 0, testhashs64_fnv1: 0, testhashu64_fnv1: 0, \
1801             testhashs32_fnv1a: 0, testhashu32_fnv1a: 0, testhashs64_fnv1a: 0, \
1802             testhashu64_fnv1a: 0, testarrayofbools: None, testf: 3.14159, \
1803             testf2: 3.00000, testf3: 0.00000, testarrayofstring2: None, \
1804             testarrayofsortedstruct: None, flex: None, test5: None, \
1805             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: None, \
1814             native_inline: None, long_enum_non_enum_default: (empty), \
1815             long_enum_normal_default: LongOne, nan_default: NaN, inf_default: \
1816             inf, positive_inf_default: inf, infinity_default: inf, \
1817             positive_infinity_default: inf, negative_inf_default: -inf, \
1818             negative_infinity_default: -inf, double_inf_default: inf }"
1819         );
1820     }
1821 
1822     #[test]
1823     #[cfg(not(miri))]  // slow.
generated_code_creates_correct_example_repeatedly_with_reset()1824     fn generated_code_creates_correct_example_repeatedly_with_reset() {
1825         let b = &mut flatbuffers::FlatBufferBuilder::new();
1826         for _ in 0..100 {
1827             create_serialized_example_with_generated_code(b);
1828             {
1829                 let buf = b.finished_data();
1830                 serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1831             }
1832             b.reset();
1833         }
1834     }
1835 
1836     #[test]
library_code_creates_correct_example()1837     fn library_code_creates_correct_example() {
1838         let b = &mut flatbuffers::FlatBufferBuilder::new();
1839         create_serialized_example_with_library_code(b);
1840         let buf = b.finished_data();
1841         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1842     }
1843 
1844     #[test]
1845     #[cfg(not(miri))]  // slow.
library_code_creates_correct_example_repeatedly_with_reset()1846     fn library_code_creates_correct_example_repeatedly_with_reset() {
1847         let b = &mut flatbuffers::FlatBufferBuilder::new();
1848         for _ in 0..100 {
1849             create_serialized_example_with_library_code(b);
1850             {
1851                 let buf = b.finished_data();
1852                 serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1853             }
1854             b.reset();
1855         }
1856     }
1857 }
1858 
1859 #[cfg(not(feature = "no_std"))]
1860 #[cfg(test)]
1861 mod read_examples_from_other_language_ports {
1862     extern crate flatbuffers;
1863 
1864     use std::println;
1865 
1866     use super::load_file;
1867     use super::serialized_example_is_accessible_and_correct;
1868 
1869     #[test]
gold_cpp_example_data_is_accessible_and_correct()1870     fn gold_cpp_example_data_is_accessible_and_correct() {
1871         let buf = load_file("../monsterdata_test.mon").expect("missing monsterdata_test.mon");
1872         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1873     }
1874     #[test]
java_wire_example_data_is_accessible_and_correct()1875     fn java_wire_example_data_is_accessible_and_correct() {
1876         let buf = load_file("../monsterdata_java_wire.mon");
1877         if buf.is_err() {
1878             println!("skipping java wire test because it is not present");
1879             return;
1880         }
1881         let buf = buf.unwrap();
1882         serialized_example_is_accessible_and_correct(&buf[..], true, false).unwrap();
1883     }
1884     #[test]
java_wire_size_prefixed_example_data_is_accessible_and_correct()1885     fn java_wire_size_prefixed_example_data_is_accessible_and_correct() {
1886         let buf = load_file("../monsterdata_java_wire_sp.mon");
1887         if buf.is_err() {
1888             println!("skipping java wire test because it is not present");
1889             return;
1890         }
1891         let buf = buf.unwrap();
1892         serialized_example_is_accessible_and_correct(&buf[..], true, true).unwrap();
1893     }
1894 }
1895 
1896 #[cfg(test)]
1897 mod generated_code_asserts {
1898     extern crate flatbuffers;
1899 
1900     use super::my_game;
1901 
1902     #[test]
1903     #[should_panic]
monster_builder_fails_when_name_is_missing()1904     fn monster_builder_fails_when_name_is_missing() {
1905         let b = &mut flatbuffers::FlatBufferBuilder::new();
1906         my_game::example::Monster::create(b, &my_game::example::MonsterArgs{..Default::default()});
1907     }
1908 }
1909 
1910 #[cfg(test)]
1911 mod generated_key_comparisons {
1912     extern crate flatbuffers;
1913 
1914     use super::my_game;
1915 
1916     #[test]
struct_ability_key_compare_less_than()1917     fn struct_ability_key_compare_less_than() {
1918         let a = my_game::example::Ability::new(1, 2);
1919         let b = my_game::example::Ability::new(2, 1);
1920         let c = my_game::example::Ability::new(3, 3);
1921 
1922         assert_eq!(a.key_compare_less_than(&a), false);
1923         assert_eq!(b.key_compare_less_than(&b), false);
1924         assert_eq!(c.key_compare_less_than(&c), false);
1925 
1926         assert_eq!(a.key_compare_less_than(&b), true);
1927         assert_eq!(a.key_compare_less_than(&c), true);
1928 
1929         assert_eq!(b.key_compare_less_than(&a), false);
1930         assert_eq!(b.key_compare_less_than(&c), true);
1931 
1932         assert_eq!(c.key_compare_less_than(&a), false);
1933         assert_eq!(c.key_compare_less_than(&b), false);
1934     }
1935 
1936     #[test]
struct_key_compare_with_value()1937     fn struct_key_compare_with_value() {
1938         let a = my_game::example::Ability::new(1, 2);
1939 
1940         assert_eq!(a.key_compare_with_value(0), ::core::cmp::Ordering::Greater);
1941         assert_eq!(a.key_compare_with_value(1), ::core::cmp::Ordering::Equal);
1942         assert_eq!(a.key_compare_with_value(2), ::core::cmp::Ordering::Less);
1943     }
1944 
1945     #[test]
struct_key_compare_less_than()1946     fn struct_key_compare_less_than() {
1947         let a = my_game::example::Ability::new(1, 2);
1948         let b = my_game::example::Ability::new(2, 1);
1949         let c = my_game::example::Ability::new(3, 3);
1950 
1951         assert_eq!(a.key_compare_less_than(&a), false);
1952         assert_eq!(b.key_compare_less_than(&b), false);
1953         assert_eq!(c.key_compare_less_than(&c), false);
1954 
1955         assert_eq!(a.key_compare_less_than(&b), true);
1956         assert_eq!(a.key_compare_less_than(&c), true);
1957 
1958         assert_eq!(b.key_compare_less_than(&a), false);
1959         assert_eq!(b.key_compare_less_than(&c), true);
1960 
1961         assert_eq!(c.key_compare_less_than(&a), false);
1962         assert_eq!(c.key_compare_less_than(&b), false);
1963     }
1964 
1965     #[test]
table_key_compare_with_value()1966     fn table_key_compare_with_value() {
1967         // setup
1968         let builder = &mut flatbuffers::FlatBufferBuilder::new();
1969         super::create_serialized_example_with_library_code(builder);
1970         let buf = builder.finished_data();
1971         let a = my_game::example::root_as_monster(buf).unwrap();
1972 
1973         // preconditions
1974         assert_eq!(a.name(), "MyMonster");
1975 
1976         assert_eq!(a.key_compare_with_value("AAA"), ::core::cmp::Ordering::Greater);
1977         assert_eq!(a.key_compare_with_value("MyMonster"), ::core::cmp::Ordering::Equal);
1978         assert_eq!(a.key_compare_with_value("ZZZ"), ::core::cmp::Ordering::Less);
1979     }
1980 
1981     #[test]
table_key_compare_less_than()1982     fn table_key_compare_less_than() {
1983         // setup
1984         let builder = &mut flatbuffers::FlatBufferBuilder::new();
1985         super::create_serialized_example_with_library_code(builder);
1986         let buf = builder.finished_data();
1987         let a = my_game::example::root_as_monster(buf).unwrap();
1988         let b = a.test_as_monster().unwrap();
1989 
1990         // preconditions
1991         assert_eq!(a.name(), "MyMonster");
1992         assert_eq!(b.name(), "Fred");
1993 
1994         assert_eq!(a.key_compare_less_than(&a), false);
1995         assert_eq!(a.key_compare_less_than(&b), false);
1996 
1997         assert_eq!(b.key_compare_less_than(&a), true);
1998         assert_eq!(b.key_compare_less_than(&b), false);
1999     }
2000 }
2001 
2002 #[cfg(test)]
2003 mod included_schema_generated_code {
2004 
2005     #[test]
2006     #[allow(unused_imports)]
namespace_test_mod_is_importable()2007     fn namespace_test_mod_is_importable() {
2008         use super::namespace_test_generated::{
2009             namespace_a,
2010             namespace_a::namespace_b,
2011             namespace_c,
2012         };
2013 
2014     }
2015 }
2016 
2017 #[cfg(test)]
2018 mod builder_asserts {
2019     extern crate flatbuffers;
2020 
2021     #[test]
2022     #[should_panic]
end_table_should_panic_when_not_in_table()2023     fn end_table_should_panic_when_not_in_table() {
2024         let mut b = flatbuffers::FlatBufferBuilder::new();
2025         b.end_table(flatbuffers::WIPOffset::new(0));
2026     }
2027 
2028     #[test]
2029     #[should_panic]
create_string_should_panic_when_in_table()2030     fn create_string_should_panic_when_in_table() {
2031         let mut b = flatbuffers::FlatBufferBuilder::new();
2032         b.start_table();
2033         b.create_string("foo");
2034     }
2035 
2036     #[test]
2037     #[should_panic]
create_byte_string_should_panic_when_in_table()2038     fn create_byte_string_should_panic_when_in_table() {
2039         let mut b = flatbuffers::FlatBufferBuilder::new();
2040         b.start_table();
2041         b.create_byte_string(b"foo");
2042     }
2043 
2044     #[test]
2045     #[should_panic]
push_struct_slot_should_panic_when_not_in_table()2046     fn push_struct_slot_should_panic_when_not_in_table() {
2047         #[derive(Copy, Clone, Debug, PartialEq)]
2048         #[repr(C, packed)]
2049         struct foo { }
2050         impl<'b> flatbuffers::Push for &'b foo {
2051             type Output = foo;
2052             unsafe fn push<'a>(&'a self, _dst: &'a mut [u8], _written_len: usize) { }
2053         }
2054         let mut b = flatbuffers::FlatBufferBuilder::new();
2055         b.push_slot_always(0, &foo{});
2056     }
2057 
2058     #[test]
2059     #[should_panic]
finished_bytes_should_panic_when_table_is_not_finished()2060     fn finished_bytes_should_panic_when_table_is_not_finished() {
2061         let mut b = flatbuffers::FlatBufferBuilder::new();
2062         b.start_table();
2063         b.finished_data();
2064     }
2065 
2066     #[test]
2067     #[should_panic]
required_panics_when_field_not_set()2068     fn required_panics_when_field_not_set() {
2069         let mut b = flatbuffers::FlatBufferBuilder::new();
2070         let start = b.start_table();
2071         let o = b.end_table(start);
2072         b.required(o, 4 /* byte offset to first field */, "test field");
2073     }
2074 }
2075 
2076 #[cfg(test)]
2077 mod follow_impls {
2078     extern crate flatbuffers;
2079     use flatbuffers::Follow;
2080     use flatbuffers::field_index_to_field_offset as fi2fo;
2081 
2082     use alloc::vec::Vec;
2083 
2084     // Define a test struct to use in a few tests. This replicates the work that the code generator
2085     // would normally do when defining a FlatBuffer struct. For reference, compare the following
2086     // `FooStruct` code with the code generated for the `Vec3` struct in
2087     // `../../monster_test/mod.rs`.
2088     use flatbuffers::EndianScalar;
2089     #[derive(Copy, Clone, Debug, PartialEq)]
2090     #[repr(C, packed)]
2091     struct FooStruct {
2092         a: i8,
2093         b: u8,
2094         c: i16,
2095     }
2096     impl FooStruct {
new(_a: i8, _b: u8, _c: i16) -> Self2097         fn new(_a: i8, _b: u8, _c: i16) -> Self {
2098             FooStruct {
2099                 a: _a.to_little_endian(),
2100                 b: _b.to_little_endian(),
2101                 c: _c.to_little_endian(),
2102             }
2103         }
2104     }
2105     impl<'a> flatbuffers::Follow<'a> for FooStruct {
2106         type Inner = &'a FooStruct;
2107         #[inline(always)]
follow(buf: &'a [u8], loc: usize) -> Self::Inner2108         unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
2109             <&'a FooStruct>::follow(buf, loc)
2110         }
2111     }
2112     impl<'a> flatbuffers::Follow<'a> for &'a FooStruct {
2113         type Inner = &'a FooStruct;
2114         #[inline(always)]
follow(buf: &'a [u8], loc: usize) -> Self::Inner2115         unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
2116             flatbuffers::follow_cast_ref::<FooStruct>(buf, loc)
2117         }
2118     }
2119 
2120     #[test]
to_u8()2121     fn to_u8() {
2122         let vec: Vec<u8> = vec![255, 3];
2123         let fs: flatbuffers::FollowStart<u8> = flatbuffers::FollowStart::new();
2124         assert_eq!(unsafe { fs.self_follow(&vec[..], 1) }, 3);
2125     }
2126 
2127     #[test]
to_u16()2128     fn to_u16() {
2129         let vec: Vec<u8> = vec![255, 255, 3, 4];
2130         let fs: flatbuffers::FollowStart<u16> = flatbuffers::FollowStart::new();
2131         assert_eq!(unsafe { fs.self_follow(&vec[..], 2) }, 1027);
2132     }
2133 
2134     #[test]
to_f32()2135     fn to_f32() {
2136         let vec: Vec<u8> = vec![255, 255, 255, 255, /* start of value */ 208, 15, 73, 64];
2137         let fs: flatbuffers::FollowStart<f32> = flatbuffers::FollowStart::new();
2138         assert_eq!(unsafe { fs.self_follow(&vec[..], 4) }, 3.14159);
2139     }
2140 
2141     #[test]
to_string()2142     fn to_string() {
2143         let vec: Vec<u8> = vec![255,255,255,255, 3, 0, 0, 0, 'f' as u8, 'o' as u8, 'o' as u8, 0];
2144         let off: flatbuffers::FollowStart<&str> = flatbuffers::FollowStart::new();
2145         assert_eq!(unsafe { off.self_follow(&vec[..], 4) }, "foo");
2146     }
2147 
2148     #[test]
to_byte_slice()2149     fn to_byte_slice() {
2150         let vec: Vec<u8> = vec![255, 255, 255, 255, 4, 0, 0, 0, 1, 2, 3, 4];
2151         let off: flatbuffers::FollowStart<flatbuffers::Vector<u8>> = flatbuffers::FollowStart::new();
2152         assert_eq!(unsafe { off.self_follow(&vec[..], 4).bytes() }, &[1, 2, 3, 4][..]);
2153     }
2154 
2155     #[test]
to_vector_of_u16()2156     fn to_vector_of_u16() {
2157         let vec: Vec<u8> = vec![255, 255, 255, 255, 2, 0, 0, 0, 1, 2, 3, 4];
2158         let off: flatbuffers::FollowStart<flatbuffers::Vector<u16>> = flatbuffers::FollowStart::new();
2159         assert_eq!(unsafe { off.self_follow(&vec[..], 4).len() }, 2);
2160         assert_eq!(unsafe { off.self_follow(&vec[..], 4).get(0) }, 513);
2161         assert_eq!(unsafe { off.self_follow(&vec[..], 4).get(1) }, 1027);
2162     }
2163 
2164     #[test]
to_struct()2165     fn to_struct() {
2166         let vec: Vec<u8> = vec![255, 255, 255, 255, 1, 2, 3, 4];
2167         let off: flatbuffers::FollowStart<&FooStruct> = flatbuffers::FollowStart::new();
2168         assert_eq!(unsafe { *off.self_follow(&vec[..], 4) }, FooStruct::new(1, 2, 1027));
2169     }
2170 
2171     #[test]
to_vector_of_offset_to_string_elements()2172     fn to_vector_of_offset_to_string_elements() {
2173         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];
2174         let s: flatbuffers::FollowStart<flatbuffers::Vector<flatbuffers::ForwardsUOffset<&str>>> = flatbuffers::FollowStart::new();
2175         assert_eq!(unsafe {s.self_follow(&buf[..], 0).len() }, 1);
2176         assert_eq!(unsafe { s.self_follow(&buf[..], 0).get(0) }, "foo");
2177     }
2178 
2179     #[test]
to_vector_of_struct_elements()2180     fn to_vector_of_struct_elements() {
2181         let buf: Vec<u8> = vec![1, 0, 0, 0, /* struct data */ 1, 2, 3, 4];
2182         let fs: flatbuffers::FollowStart<flatbuffers::Vector<FooStruct>> = flatbuffers::FollowStart::new();
2183         assert_eq!(unsafe { fs.self_follow(&buf[..], 0).len() }, 1);
2184         assert_eq!(unsafe { fs.self_follow(&buf[..], 0).get(0) }, &FooStruct::new(1, 2, 1027));
2185     }
2186 
2187     #[test]
to_root_to_empty_table()2188     fn to_root_to_empty_table() {
2189         let buf: Vec<u8> = vec![
2190             12, 0, 0, 0, // offset to root table
2191             // enter vtable
2192             4, 0, // vtable len
2193             0, 0, // inline size
2194             255, 255, 255, 255, // canary
2195             // enter table
2196             8, 0, 0, 0, // vtable location
2197         ];
2198         unsafe {
2199             let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2200             assert_eq!(fs.self_follow(&buf[..], 0), flatbuffers::Table::new(&buf[..], 12));
2201         }
2202     }
2203 
2204     #[test]
to_root_table_get_slot_scalar_u8()2205     fn to_root_table_get_slot_scalar_u8() {
2206         let buf: Vec<u8> = vec![
2207             14, 0, 0, 0, // offset to root table
2208             // enter vtable
2209             6, 0, // vtable len
2210             2, 0, // inline size
2211             5, 0, // value loc
2212             255, 255, 255, 255, // canary
2213             // enter table
2214             10, 0, 0, 0, // vtable location
2215             0, 99 // value (with padding)
2216         ];
2217         unsafe {
2218             let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2219             let tab = fs.self_follow(&buf[..], 0);
2220             assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(99));
2221         }
2222     }
2223 
2224     #[test]
to_root_to_table_get_slot_scalar_u8_default_via_vtable_len()2225     fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_len() {
2226         let buf: Vec<u8> = vec![
2227             12, 0, 0, 0, // offset to root table
2228             // enter vtable
2229             4, 0, // vtable len
2230             2, 0, // inline size
2231             255, 255, 255, 255, // canary
2232             // enter table
2233             8, 0, 0, 0, // vtable location
2234         ];
2235         unsafe {
2236             let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2237             let tab = fs.self_follow(&buf[..], 0);
2238             assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
2239         }
2240     }
2241 
2242     #[test]
to_root_to_table_get_slot_scalar_u8_default_via_vtable_zero()2243     fn to_root_to_table_get_slot_scalar_u8_default_via_vtable_zero() {
2244         let buf: Vec<u8> = vec![
2245             14, 0, 0, 0, // offset to root table
2246             // enter vtable
2247             6, 0, // vtable len
2248             2, 0, // inline size
2249             0, 0, // zero means use the default value
2250             255, 255, 255, 255, // canary
2251             // enter table
2252             10, 0, 0, 0, // vtable location
2253         ];
2254         unsafe {
2255             let fs: flatbuffers::FollowStart<flatbuffers::ForwardsUOffset<flatbuffers::Table>> = flatbuffers::FollowStart::new();
2256             let tab = fs.self_follow(&buf[..], 0);
2257             assert_eq!(tab.get::<u8>(fi2fo(0), Some(123)), Some(123));
2258         }
2259     }
2260 
2261     #[test]
to_root_to_table_get_slot_string_multiple_types()2262     fn to_root_to_table_get_slot_string_multiple_types() {
2263         let buf: Vec<u8> = vec![
2264             14, 0, 0, 0, // offset to root table
2265             // enter vtable
2266             6, 0, // vtable len
2267             2, 0, // inline size
2268             4, 0, // value loc
2269             255, 255, 255, 255, // canary
2270             // enter table
2271             10, 0, 0, 0, // vtable location
2272             8, 0, 0, 0, // offset to string
2273             // leave table
2274             255, 255, 255, 255, // canary
2275             // enter string
2276             3, 0, 0, 0, 109, 111, 111, 0 // string length and contents
2277         ];
2278         unsafe {
2279             let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
2280             assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), None), Some("moo"));
2281             let byte_vec = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap().bytes();
2282             assert_eq!(byte_vec, &vec![109, 111, 111][..]);
2283             let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), None).unwrap();
2284             assert_eq!(v.len(), 3);
2285             assert_eq!(v.get(0), 109);
2286             assert_eq!(v.get(1), 111);
2287             assert_eq!(v.get(2), 111);
2288         }
2289     }
2290 
2291     #[test]
to_root_to_table_get_slot_string_multiple_types_default_via_vtable_len()2292     fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_len() {
2293         let buf: Vec<u8> = vec![
2294             12, 0, 0, 0, // offset to root table
2295             // enter vtable
2296             4, 0, // vtable len
2297             4, 0, // table inline len
2298             255, 255, 255, 255, // canary
2299             // enter table
2300             8, 0, 0, 0, // vtable location
2301         ];
2302 
2303         unsafe {
2304             let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
2305             assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
2306             #[cfg(target_endian = "little")]
2307             {
2308                 assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
2309             }
2310 
2311             let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
2312             let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
2313             let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
2314             assert_eq!(v.len(), 3);
2315             assert_eq!(v.get(0), 70);
2316             assert_eq!(v.get(1), 71);
2317             assert_eq!(v.get(2), 72);
2318         }
2319     }
2320 
2321     #[test]
to_root_to_table_get_slot_string_multiple_types_default_via_vtable_zero()2322     fn to_root_to_table_get_slot_string_multiple_types_default_via_vtable_zero() {
2323         let buf: Vec<u8> = vec![
2324             14, 0, 0, 0, // offset to root table
2325             // enter vtable
2326             6, 0, // vtable len
2327             2, 0, // inline size
2328             0, 0, // value loc
2329             255, 255, 255, 255, // canary
2330             // enter table
2331             10, 0, 0, 0, // vtable location
2332         ];
2333         unsafe {
2334             let tab = <flatbuffers::ForwardsUOffset<flatbuffers::Table>>::follow(&buf[..], 0);
2335             assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&str>>(fi2fo(0), Some("abc")), Some("abc"));
2336             #[cfg(target_endian = "little")]
2337             {
2338                 assert_eq!(tab.get::<flatbuffers::ForwardsUOffset<&[u8]>>(fi2fo(0), Some(&vec![70, 71, 72][..])), Some(&vec![70, 71, 72][..]));
2339             }
2340 
2341             let default_vec_buf: Vec<u8> = vec![3, 0, 0, 0, 70, 71, 72, 0];
2342             let default_vec = flatbuffers::Vector::new(&default_vec_buf[..], 0);
2343             let v = tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<u8>>>(fi2fo(0), Some(default_vec)).unwrap();
2344             assert_eq!(v.len(), 3);
2345             assert_eq!(v.get(0), 70);
2346             assert_eq!(v.get(1), 71);
2347             assert_eq!(v.get(2), 72);
2348         }
2349     }
2350 }
2351 
2352 #[cfg(test)]
2353 mod push_impls {
2354     extern crate flatbuffers;
2355 
2356     use super::my_game;
2357 
check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8])2358     fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
2359         let got = b.unfinished_data();
2360         assert_eq!(want, got);
2361     }
2362 
2363     #[test]
push_u8()2364     fn push_u8() {
2365         let mut b = flatbuffers::FlatBufferBuilder::new();
2366         b.push(123u8);
2367         check(&b, &[123]);
2368     }
2369 
2370     #[test]
push_u64()2371     fn push_u64() {
2372         let mut b = flatbuffers::FlatBufferBuilder::new();
2373         b.push(0x12345678);
2374         check(&b, &[0x78, 0x56, 0x34, 0x12]);
2375     }
2376 
2377     #[test]
push_f64()2378     fn push_f64() {
2379         let mut b = flatbuffers::FlatBufferBuilder::new();
2380         b.push(3.14159265359f64);
2381         check(&b, &[234, 46, 68, 84, 251, 33, 9, 64]);
2382     }
2383 
2384     #[test]
push_generated_struct()2385     fn push_generated_struct() {
2386         let mut b = flatbuffers::FlatBufferBuilder::new();
2387         b.push(my_game::example::Test::new(10, 20));
2388         check(&b, &[10, 0, 20, 0]);
2389     }
2390 
2391     #[test]
push_u8_vector_with_offset_with_alignment()2392     fn push_u8_vector_with_offset_with_alignment() {
2393         let mut b = flatbuffers::FlatBufferBuilder::new();
2394         let off = b.create_vector(&[1u8, 2, 3, 4, 5, 6, 7, 8, 9][..]);
2395         b.push(off);
2396         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]);
2397     }
2398 
2399     #[test]
push_u8_u16_alignment()2400     fn push_u8_u16_alignment() {
2401         let mut b = flatbuffers::FlatBufferBuilder::new();
2402         b.push(1u8);
2403         b.push(2u16);
2404         check(&b, &[2, 0, 0, 1]);
2405     }
2406 
2407     #[test]
push_u8_u32_alignment()2408     fn push_u8_u32_alignment() {
2409         let mut b = flatbuffers::FlatBufferBuilder::new();
2410         b.push(1u8);
2411         b.push(2u32);
2412         check(&b, &[2, 0, 0, 0, 0, 0, 0, 1]);
2413     }
2414 
2415     #[test]
push_u8_u64_alignment()2416     fn push_u8_u64_alignment() {
2417         let mut b = flatbuffers::FlatBufferBuilder::new();
2418         b.push(1u8);
2419         b.push(2u64);
2420         check(&b, &[2, 0, 0, 0,
2421                     0, 0, 0, 0,
2422                     0, 0, 0, 0,
2423                     0, 0, 0, 1]);
2424     }
2425 }
2426 
2427 #[cfg(test)]
2428 mod vtable_deduplication {
2429     extern crate flatbuffers;
2430     use flatbuffers::field_index_to_field_offset as fi2fo;
2431 
check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8])2432     fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
2433         let got = b.unfinished_data();
2434         assert_eq!(want, got);
2435     }
2436 
2437     #[test]
one_empty_table()2438     fn one_empty_table() {
2439         let mut b = flatbuffers::FlatBufferBuilder::new();
2440         let start0 = b.start_table();
2441         b.end_table(start0);
2442         check(&b, &[
2443               4, 0, // vtable size in bytes
2444               4, 0, // object inline data in bytes
2445 
2446               4, 0, 0, 0, // backwards offset to vtable
2447         ]);
2448     }
2449 
2450     #[test]
two_empty_tables_are_deduplicated()2451     fn two_empty_tables_are_deduplicated() {
2452         let mut b = flatbuffers::FlatBufferBuilder::new();
2453         let start0 = b.start_table();
2454         b.end_table(start0);
2455         let start1 = b.start_table();
2456         b.end_table(start1);
2457         check(&b, &[
2458               252, 255, 255, 255, // forwards offset to vtable
2459 
2460               4, 0, // vtable size in bytes
2461               4, 0, // object inline data in bytes
2462 
2463               4, 0, 0, 0, // backwards offset to vtable
2464         ]);
2465     }
2466 
2467     #[test]
two_tables_with_two_conveniently_sized_inline_elements_are_deduplicated()2468     fn two_tables_with_two_conveniently_sized_inline_elements_are_deduplicated() {
2469         let mut b = flatbuffers::FlatBufferBuilder::new();
2470         let start0 = b.start_table();
2471         b.push_slot::<u64>(fi2fo(0), 100, 0);
2472         b.push_slot::<u32>(fi2fo(1), 101, 0);
2473         b.end_table(start0);
2474         let start1 = b.start_table();
2475         b.push_slot::<u64>(fi2fo(0), 200, 0);
2476         b.push_slot::<u32>(fi2fo(1), 201, 0);
2477         b.end_table(start1);
2478         check(&b, &[
2479               240, 255, 255, 255, // forwards offset to vtable
2480 
2481               201, 0, 0, 0, // value #1
2482               200, 0, 0, 0, 0, 0, 0, 0, // value #0
2483 
2484               8, 0, // vtable size in bytes
2485               16, 0, // object inline data in bytes
2486               8, 0, // offset in object for value #0
2487               4, 0, // offset in object for value #1
2488 
2489               8, 0, 0, 0, // backwards offset to vtable
2490               101, 0, 0, 0, // value #1
2491               100, 0, 0, 0, 0, 0, 0, 0 // value #0
2492         ]);
2493     }
2494 
2495     #[cfg(not(miri))]  // slow.
2496     #[test]
many_identical_tables_use_few_vtables()2497     fn many_identical_tables_use_few_vtables() {
2498         let mut b = flatbuffers::FlatBufferBuilder::new();
2499         for _ in 0..1000 {
2500             let start = b.start_table();
2501             b.push_slot::<u8>(fi2fo(0), 100, 0);
2502             b.push_slot::<u32>(fi2fo(1), 101, 0);
2503             b.end_table(start);
2504         }
2505         assert!(b.num_written_vtables() <= 10);
2506     }
2507 }
2508 
2509 #[cfg(test)]
2510 mod byte_layouts {
2511     extern crate flatbuffers;
2512     use flatbuffers::field_index_to_field_offset as fi2fo;
2513 
check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8])2514     fn check<'a>(b: &'a flatbuffers::FlatBufferBuilder, want: &'a [u8]) {
2515         let got = b.unfinished_data();
2516         assert_eq!(want, got);
2517     }
2518 
2519     #[test]
layout_01_basic_numbers()2520     fn layout_01_basic_numbers() {
2521         let mut b = flatbuffers::FlatBufferBuilder::new();
2522         b.push(true);
2523         check(&b, &[1]);
2524         b.push(-127i8);
2525         check(&b, &[129, 1]);
2526         b.push(255u8);
2527         check(&b, &[255, 129, 1]);
2528         b.push(-32222i16);
2529         check(&b, &[0x22, 0x82, 0, 255, 129, 1]); // first pad
2530         b.push(0xFEEEu16);
2531         check(&b, &[0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]); // no pad this time
2532         b.push(-53687092i32);
2533         check(&b, &[204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
2534         b.push(0x98765432u32);
2535         check(&b, &[0x32, 0x54, 0x76, 0x98, 204, 204, 204, 252, 0xEE, 0xFE, 0x22, 0x82, 0, 255, 129, 1]);
2536     }
2537 
2538     #[test]
layout_01b_bigger_numbers()2539     fn layout_01b_bigger_numbers() {
2540         let mut b = flatbuffers::FlatBufferBuilder::new();
2541         b.push(0x1122334455667788u64);
2542         check(&b, &[0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]);
2543     }
2544 
2545     #[test]
layout_02_1xbyte_vector()2546     fn layout_02_1xbyte_vector() {
2547         let mut b = flatbuffers::FlatBufferBuilder::new();
2548         check(&b, &[]);
2549         b.start_vector::<u8>(1);
2550         check(&b, &[0, 0, 0]); // align to 4bytes
2551         b.push(1u8);
2552         check(&b, &[1, 0, 0, 0]);
2553         b.end_vector::<u8>(1);
2554         check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
2555     }
2556 
2557     #[test]
layout_03_2xbyte_vector()2558     fn layout_03_2xbyte_vector() {
2559         let mut b = flatbuffers::FlatBufferBuilder::new();
2560         b.start_vector::<u8>(2);
2561         check(&b, &[0, 0]); // align to 4bytes
2562         b.push(1u8);
2563         check(&b, &[1, 0, 0]);
2564         b.push(2u8);
2565         check(&b, &[2, 1, 0, 0]);
2566         b.end_vector::<u8>(2);
2567         check(&b, &[2, 0, 0, 0, 2, 1, 0, 0]); // padding
2568     }
2569 
2570     #[test]
layout_03b_11xbyte_vector_matches_builder_size()2571     fn layout_03b_11xbyte_vector_matches_builder_size() {
2572         let mut b = flatbuffers::FlatBufferBuilder::with_capacity(12);
2573         b.start_vector::<u8>(8);
2574 
2575         let mut gold = vec![0u8; 0];
2576         check(&b, &gold[..]);
2577 
2578         for i in 1u8..=8 {
2579             b.push(i);
2580             gold.insert(0, i);
2581             check(&b, &gold[..]);
2582         }
2583         b.end_vector::<u8>(8);
2584         let want = vec![8u8, 0, 0, 0,  8, 7, 6, 5, 4, 3, 2, 1];
2585         check(&b, &want[..]);
2586     }
2587     #[test]
layout_04_1xuint16_vector()2588     fn layout_04_1xuint16_vector() {
2589         let mut b = flatbuffers::FlatBufferBuilder::new();
2590         b.start_vector::<u16>(1);
2591         check(&b, &[0, 0]); // align to 4bytes
2592         b.push(1u16);
2593         check(&b, &[1, 0, 0, 0]);
2594         b.end_vector::<u16>(1);
2595         check(&b, &[1, 0, 0, 0, 1, 0, 0, 0]); // padding
2596     }
2597 
2598     #[test]
layout_05_2xuint16_vector()2599     fn layout_05_2xuint16_vector() {
2600         let mut b = flatbuffers::FlatBufferBuilder::new();
2601         let _off = b.start_vector::<u16>(2);
2602         check(&b, &[]); // align to 4bytes
2603         b.push(0xABCDu16);
2604         check(&b, &[0xCD, 0xAB]);
2605         b.push(0xDCBAu16);
2606         check(&b, &[0xBA, 0xDC, 0xCD, 0xAB]);
2607         b.end_vector::<u16>(2);
2608         check(&b, &[2, 0, 0, 0, 0xBA, 0xDC, 0xCD, 0xAB]);
2609     }
2610 
2611     #[test]
layout_06_create_string()2612     fn layout_06_create_string() {
2613         let mut b = flatbuffers::FlatBufferBuilder::new();
2614         let off0 = b.create_string("foo");
2615         assert_eq!(8, off0.value());
2616         check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
2617         let off1 = b.create_string("moop");
2618         assert_eq!(20, off1.value());
2619         check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
2620                     \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
2621     }
2622 
2623     #[test]
layout_06b_create_string_unicode()2624     fn layout_06b_create_string_unicode() {
2625         let mut b = flatbuffers::FlatBufferBuilder::new();
2626         // These characters are chinese from blog.golang.org/strings
2627         // We use escape codes here so that editors without unicode support
2628         // aren't bothered:
2629         let uni_str = "\u{65e5}\u{672c}\u{8a9e}";
2630         let off0 = b.create_string(uni_str);
2631         assert_eq!(16, off0.value());
2632         check(&b, &[9, 0, 0, 0, 230, 151, 165, 230, 156, 172, 232, 170, 158, 0, //  null-terminated, 2-byte pad
2633                     0, 0]);
2634     }
2635 
2636     #[test]
layout_06c_create_byte_string()2637     fn layout_06c_create_byte_string() {
2638         let mut b = flatbuffers::FlatBufferBuilder::new();
2639         let off0 = b.create_byte_string(b"foo");
2640         assert_eq!(8, off0.value());
2641         check(&b, b"\x03\x00\x00\x00foo\x00"); // 0-terminated, no pad
2642         let off1 = b.create_byte_string(b"moop");
2643         assert_eq!(20, off1.value());
2644         check(&b, b"\x04\x00\x00\x00moop\x00\x00\x00\x00\
2645                     \x03\x00\x00\x00foo\x00"); // 0-terminated, 3-byte pad
2646     }
2647 
2648     #[test]
layout_07_empty_vtable()2649     fn layout_07_empty_vtable() {
2650         let mut b = flatbuffers::FlatBufferBuilder::new();
2651         let off0 = b.start_table();
2652         check(&b, &[]);
2653         b.end_table(off0);
2654         check(&b, &[4, 0, // vtable length
2655                     4, 0, // length of table including vtable offset
2656                     4, 0, 0, 0]); // offset for start of vtable
2657     }
2658 
2659     #[test]
layout_08_vtable_with_one_true_bool()2660     fn layout_08_vtable_with_one_true_bool() {
2661         let mut b = flatbuffers::FlatBufferBuilder::new();
2662         check(&b, &[]);
2663         let off0 = b.start_table();
2664         assert_eq!(0, off0.value());
2665         check(&b, &[]);
2666         b.push_slot(fi2fo(0), true, false);
2667         check(&b, &[1]);
2668         let off1 = b.end_table(off0);
2669         assert_eq!(8, off1.value());
2670         check(&b, &[
2671               6, 0, // vtable bytes
2672               8, 0, // length of object including vtable offset
2673               7, 0, // start of bool value
2674               6, 0, 0, 0, // offset for start of vtable (int32)
2675               0, 0, 0, // padded to 4 bytes
2676               1, // bool value
2677         ]);
2678     }
2679 
2680     #[test]
layout_09_vtable_with_one_default_bool()2681     fn layout_09_vtable_with_one_default_bool() {
2682         let mut b = flatbuffers::FlatBufferBuilder::new();
2683         check(&b, &[]);
2684         let off = b.start_table();
2685         check(&b, &[]);
2686         b.push_slot(fi2fo(0), false, false);
2687         b.end_table(off);
2688         check(&b, &[
2689              4, 0, // vtable bytes
2690              4, 0, // end of object from here
2691              // entry 1 is zero and not stored.
2692              4, 0, 0, 0, // offset for start of vtable (int32)
2693         ]);
2694     }
2695 
2696     #[test]
layout_09b_vtable_with_one_default_bool_force_defaults()2697     fn layout_09b_vtable_with_one_default_bool_force_defaults() {
2698         let mut b = flatbuffers::FlatBufferBuilder::new();
2699         check(&b, &[]);
2700         let off = b.start_table();
2701         check(&b, &[]);
2702         b.force_defaults(true);
2703         b.push_slot(fi2fo(0), false, false);
2704         b.end_table(off);
2705         check(&b, &[
2706             6, 0, // vtable bytes
2707             8, 0, // length of object including vtable offset
2708             7, 0, // start of bool value
2709             6, 0, 0, 0, // offset for start of vtable (int32)
2710             0, 0, 0, // padded to 4 bytes
2711             0, // bool value
2712       ]);
2713     }
2714 
2715     #[test]
layout_10_vtable_with_one_int16()2716     fn layout_10_vtable_with_one_int16() {
2717         let mut b = flatbuffers::FlatBufferBuilder::new();
2718         check(&b, &[]);
2719         let off = b.start_table();
2720         b.push_slot(fi2fo(0), 0x789Ai16, 0);
2721         b.end_table(off);
2722         check(&b, &[
2723               6, 0, // vtable bytes
2724               8, 0, // end of object from here
2725               6, 0, // offset to value
2726               6, 0, 0, 0, // offset for start of vtable (int32)
2727               0, 0, // padding to 4 bytes
2728               0x9A, 0x78,
2729         ]);
2730     }
2731 
2732     #[test]
layout_11_vtable_with_two_int16()2733     fn layout_11_vtable_with_two_int16() {
2734         let mut b = flatbuffers::FlatBufferBuilder::new();
2735         let off = b.start_table();
2736         b.push_slot(fi2fo(0), 0x3456i16, 0);
2737         b.push_slot(fi2fo(1), 0x789Ai16, 0);
2738         b.end_table(off);
2739         check(&b, &[
2740               8, 0, // vtable bytes
2741               8, 0, // end of object from here
2742               6, 0, // offset to value 0
2743               4, 0, // offset to value 1
2744               8, 0, 0, 0, // offset for start of vtable (int32)
2745               0x9A, 0x78, // value 1
2746               0x56, 0x34, // value 0
2747         ]);
2748     }
2749 
2750     #[test]
layout_12_vtable_with_int16_and_bool()2751     fn layout_12_vtable_with_int16_and_bool() {
2752         let mut b = flatbuffers::FlatBufferBuilder::new();
2753         let off = b.start_table();
2754         b.push_slot(fi2fo(0), 0x3456i16, 0);
2755         b.push_slot(fi2fo(1), true, false);
2756         b.end_table(off);
2757         check(&b, &[
2758             8, 0, // vtable bytes
2759             8, 0, // end of object from here
2760             6, 0, // offset to value 0
2761             5, 0, // offset to value 1
2762             8, 0, 0, 0, // offset for start of vtable (int32)
2763             0,          // padding
2764             1,          // value 1
2765             0x56, 0x34, // value 0
2766         ]);
2767     }
2768 
2769     #[test]
layout_12b_vtable_with_empty_vector()2770     fn layout_12b_vtable_with_empty_vector() {
2771         let mut b = flatbuffers::FlatBufferBuilder::new();
2772         b.start_vector::<u8>(0);
2773         let vecend = b.end_vector::<u8>(0);
2774         let off = b.start_table();
2775         b.push_slot_always(fi2fo(0), vecend);
2776         b.end_table(off);
2777         check(&b, &[
2778               6, 0, // vtable bytes
2779               8, 0,
2780               4, 0, // offset to vector offset
2781               6, 0, 0, 0, // offset for start of vtable (int32)
2782               4, 0, 0, 0,
2783               0, 0, 0, 0, // length of vector (not in struct)
2784         ]);
2785     }
2786 
2787     #[test]
layout_12c_vtable_with_empty_vector_of_byte_and_some_scalars()2788     fn layout_12c_vtable_with_empty_vector_of_byte_and_some_scalars() {
2789         let mut b = flatbuffers::FlatBufferBuilder::new();
2790         b.start_vector::<u8>(0);
2791         let vecend = b.end_vector::<u8>(0);
2792         let off = b.start_table();
2793         b.push_slot::<i16>(fi2fo(0), 55i16, 0);
2794         b.push_slot_always::<flatbuffers::WIPOffset<_>>(fi2fo(1), vecend);
2795         b.end_table(off);
2796         check(&b, &[
2797               8, 0, // vtable bytes
2798               12, 0,
2799               10, 0, // offset to value 0
2800               4, 0, // offset to vector offset
2801               8, 0, 0, 0, // vtable loc
2802               8, 0, 0, 0, // value 1
2803               0, 0, 55, 0, // value 0
2804 
2805               0, 0, 0, 0, // length of vector (not in struct)
2806         ]);
2807     }
2808     #[test]
layout_13_vtable_with_1_int16_and_2_vector_of_i16()2809     fn layout_13_vtable_with_1_int16_and_2_vector_of_i16() {
2810         let mut b = flatbuffers::FlatBufferBuilder::new();
2811         b.start_vector::<i16>(2);
2812         b.push(0x1234i16);
2813         b.push(0x5678i16);
2814         let vecend = b.end_vector::<i16>(2);
2815         let off = b.start_table();
2816         b.push_slot_always(fi2fo(1), vecend);
2817         b.push_slot(fi2fo(0), 55i16, 0);
2818         b.end_table(off);
2819         check(&b, &[
2820               8, 0, // vtable bytes
2821               12, 0, // length of object
2822               6, 0, // start of value 0 from end of vtable
2823               8, 0, // start of value 1 from end of buffer
2824               8, 0, 0, 0, // offset for start of vtable (int32)
2825               0, 0, // padding
2826               55, 0, // value 0
2827               4, 0, 0, 0, // vector position from here
2828               2, 0, 0, 0, // length of vector (uint32)
2829               0x78, 0x56, // vector value 1
2830               0x34, 0x12, // vector value 0
2831         ]);
2832     }
2833     #[test]
layout_14_vtable_with_1_struct_of_int8_and_int16_and_int32()2834     fn layout_14_vtable_with_1_struct_of_int8_and_int16_and_int32() {
2835         #[derive(Copy, Clone, Debug, Eq, PartialEq)]
2836         #[repr(C, packed)]
2837         struct foo {
2838             a: i32,
2839             _pad0: [u8; 2],
2840             b: i16,
2841             _pad1: [u8; 3],
2842             c: i8,
2843             _pad2: [u8; 4],
2844         }
2845         assert_eq!(::core::mem::size_of::<foo>(), 16);
2846         impl<'b> flatbuffers::Push for &'b foo {
2847             type Output = foo;
2848             unsafe fn push<'a>(&'a self, dst: &'a mut [u8], _written_len: usize) {
2849                 let src = ::core::slice::from_raw_parts(*self as *const foo as *const u8, ::core::mem::size_of::<foo>());
2850                 dst.copy_from_slice(src);
2851             }
2852         }
2853 
2854         let mut b = flatbuffers::FlatBufferBuilder::new();
2855         let off = b.start_table();
2856         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]};
2857         b.push_slot_always(fi2fo(0), &x);
2858         b.end_table(off);
2859         check(&b, &[
2860               6, 0, // vtable bytes
2861               20, 0, // end of object from here
2862               4, 0, // start of struct from here
2863               6, 0, 0, 0, // offset for start of vtable (int32)
2864 
2865               0x78, 0x56, 0x34, 0x12, // value a
2866               0, 0, // padding
2867               0x34, 0x12, // value b
2868               0, 0, 0, // padding
2869               0x12, // value c
2870               0, 0, 0, 0, // padding
2871         ]);
2872     }
2873     #[test]
layout_15_vtable_with_1_vector_of_4_int8()2874     fn layout_15_vtable_with_1_vector_of_4_int8() {
2875         let mut b = flatbuffers::FlatBufferBuilder::new();
2876         b.start_vector::<i8>(4);
2877         b.push(33i8);
2878         b.push(44i8);
2879         b.push(55i8);
2880         b.push(66i8);
2881         let vecend = b.end_vector::<i8>(4);
2882         let off = b.start_table();
2883         b.push_slot_always(fi2fo(0), vecend);
2884         b.end_table(off);
2885         check(&b, &[
2886               6, 0, // vtable bytes
2887               8, 0,
2888               4, 0, // offset of vector offset
2889               6, 0, 0, 0, // offset for start of vtable (int32)
2890               4, 0, 0, 0, // vector start offset
2891 
2892               4, 0, 0, 0, // vector length
2893               66, // vector value 1,1
2894               55, // vector value 1,0
2895               44, // vector value 0,1
2896               33, // vector value 0,0
2897         ]);
2898     }
2899 
2900     #[test]
layout_16_table_with_some_elements()2901     fn layout_16_table_with_some_elements() {
2902         let mut b = flatbuffers::FlatBufferBuilder::new();
2903         let off = b.start_table();
2904         b.push_slot(fi2fo(0), 33i8, 0);
2905         b.push_slot(fi2fo(1), 66i16, 0);
2906         let off2 = b.end_table(off);
2907         b.finish_minimal(off2);
2908 
2909         check(&b, &[
2910               12, 0, 0, 0, // root of table: points to vtable offset
2911 
2912               8, 0, // vtable bytes
2913               8, 0, // end of object from here
2914               7, 0, // start of value 0
2915               4, 0, // start of value 1
2916 
2917               8, 0, 0, 0, // offset for start of vtable (int32)
2918 
2919               66, 0, // value 1
2920               0,  // padding
2921               33, // value 0
2922         ]);
2923     }
2924 
2925     #[test]
layout_17_one_unfinished_table_and_one_finished_table()2926     fn layout_17_one_unfinished_table_and_one_finished_table() {
2927         let mut b = flatbuffers::FlatBufferBuilder::new();
2928         {
2929             let off = b.start_table();
2930             b.push_slot(fi2fo(0), 33i8, 0);
2931             b.push_slot(fi2fo(1), 44i8, 0);
2932             b.end_table(off);
2933         }
2934 
2935         {
2936             let off = b.start_table();
2937             b.push_slot(fi2fo(0), 55i8, 0);
2938             b.push_slot(fi2fo(1), 66i8, 0);
2939             b.push_slot(fi2fo(2), 77i8, 0);
2940             let off2 = b.end_table(off);
2941             b.finish_minimal(off2);
2942         }
2943 
2944         check(&b, &[
2945               16, 0, 0, 0, // root of table: points to object
2946               0, 0, // padding
2947 
2948               10, 0, // vtable bytes
2949               8, 0, // size of object
2950               7, 0, // start of value 0
2951               6, 0, // start of value 1
2952               5, 0, // start of value 2
2953               10, 0, 0, 0, // offset for start of vtable (int32)
2954               0,  // padding
2955               77, // value 2
2956               66, // value 1
2957               55, // value 0
2958 
2959               //12, 0, 0, 0, // root of table: points to object
2960 
2961               8, 0, // vtable bytes
2962               8, 0, // size of object
2963               7, 0, // start of value 0
2964               6, 0, // start of value 1
2965               8, 0, 0, 0, // offset for start of vtable (int32)
2966               0, 0, // padding
2967               44, // value 1
2968               33, // value 0
2969               ]);
2970     }
2971 
2972     #[test]
layout_18_a_bunch_of_bools()2973     fn layout_18_a_bunch_of_bools() {
2974         let mut b = flatbuffers::FlatBufferBuilder::new();
2975         let off = b.start_table();
2976         b.push_slot(fi2fo(0), true, false);
2977         b.push_slot(fi2fo(1), true, false);
2978         b.push_slot(fi2fo(2), true, false);
2979         b.push_slot(fi2fo(3), true, false);
2980         b.push_slot(fi2fo(4), true, false);
2981         b.push_slot(fi2fo(5), true, false);
2982         b.push_slot(fi2fo(6), true, false);
2983         b.push_slot(fi2fo(7), true, false);
2984         let off2 = b.end_table(off);
2985         b.finish_minimal(off2);
2986 
2987         check(&b, &[
2988               24, 0, 0, 0, // root of table: points to vtable offset
2989 
2990               20, 0, // vtable bytes
2991               12, 0, // size of object
2992               11, 0, // start of value 0
2993               10, 0, // start of value 1
2994               9, 0, // start of value 2
2995               8, 0, // start of value 3
2996               7, 0, // start of value 4
2997               6, 0, // start of value 5
2998               5, 0, // start of value 6
2999               4, 0, // start of value 7
3000               20, 0, 0, 0, // vtable offset
3001 
3002               1, // value 7
3003               1, // value 6
3004               1, // value 5
3005               1, // value 4
3006               1, // value 3
3007               1, // value 2
3008               1, // value 1
3009               1, // value 0
3010               ]);
3011     }
3012 
3013     #[test]
layout_19_three_bools()3014     fn layout_19_three_bools() {
3015         let mut b = flatbuffers::FlatBufferBuilder::new();
3016         let off = b.start_table();
3017         b.push_slot(fi2fo(0), true, false);
3018         b.push_slot(fi2fo(1), true, false);
3019         b.push_slot(fi2fo(2), true, false);
3020         let off2 = b.end_table(off);
3021         b.finish_minimal(off2);
3022 
3023         check(&b, &[
3024               16, 0, 0, 0, // root of table: points to vtable offset
3025 
3026               0, 0, // padding
3027 
3028               10, 0, // vtable bytes
3029               8, 0, // size of object
3030               7, 0, // start of value 0
3031               6, 0, // start of value 1
3032               5, 0, // start of value 2
3033               10, 0, 0, 0, // vtable offset from here
3034 
3035               0, // padding
3036               1, // value 2
3037               1, // value 1
3038               1, // value 0
3039         ]);
3040     }
3041 
3042     #[test]
layout_20_some_floats()3043     fn layout_20_some_floats() {
3044         let mut b = flatbuffers::FlatBufferBuilder::new();
3045         let off = b.start_table();
3046         b.push_slot(fi2fo(0), 1.0f32, 0.0);
3047         b.end_table(off);
3048 
3049         check(&b, &[
3050               6, 0, // vtable bytes
3051               8, 0, // size of object
3052               4, 0, // start of value 0
3053               6, 0, 0, 0, // vtable offset
3054 
3055               0, 0, 128, 63, // value 0
3056         ]);
3057     }
3058 
3059     #[test]
layout_21_vtable_defaults()3060     fn layout_21_vtable_defaults() {
3061         let mut b = flatbuffers::FlatBufferBuilder::new();
3062         let off = b.start_table();
3063         b.push_slot::<i8>(fi2fo(0), 1, 1);
3064         b.push_slot::<i8>(fi2fo(1), 3, 2);
3065         b.push_slot::<i8>(fi2fo(2), 3, 3);
3066         b.end_table(off);
3067         check(&b, &[
3068               8, 0, // vtable size in bytes
3069               8, 0, // object inline data in bytes
3070               0, 0, // entry 1/3: 0 => default
3071               7, 0, // entry 2/3: 7 => table start + 7 bytes
3072               // entry 3/3: not present => default
3073               8, 0, 0, 0,
3074               0, 0, 0,
3075               3,
3076         ]);
3077     }
3078 
3079     #[test]
layout_22_root()3080     fn layout_22_root() {
3081         let mut b = flatbuffers::FlatBufferBuilder::new();
3082         let off = b.start_table();
3083         // skipped: b.push_slot_scalar::<i16>(0, 1, 1);
3084         b.push_slot::<i16>(fi2fo(1), 3, 2);
3085         b.push_slot::<i16>(fi2fo(2), 3, 3);
3086         let table_end = b.end_table(off);
3087         b.finish_minimal(table_end);
3088         check(&b, &[
3089               12, 0, 0, 0, // root
3090 
3091               8, 0, // vtable size in bytes
3092               8, 0, // object inline data in bytes
3093               0, 0, // entry 1/3: 0 => default
3094               6, 0, // entry 2/3: 6 => table start + 6 bytes
3095               // entry 3/3: not present => default
3096               8, 0, 0, 0, // size of table data in bytes
3097               0, 0, // padding
3098               3, 0, // value 2/3
3099         ]);
3100     }
3101     #[test]
layout_23_varied_slots_and_root()3102     fn layout_23_varied_slots_and_root() {
3103         let mut b = flatbuffers::FlatBufferBuilder::new();
3104         let off = b.start_table();
3105         b.push_slot::<i16>(fi2fo(0), 1, 0);
3106         b.push_slot::<u8>(fi2fo(1), 2, 0);
3107         b.push_slot::<f32>(fi2fo(2), 3.0, 0.0);
3108         let table_end = b.end_table(off);
3109         b.finish_minimal(table_end);
3110         check(&b, &[
3111               16, 0, 0, 0, // root
3112               0, 0, // padding
3113               10, 0, // vtable bytes
3114               12, 0, // object inline data size
3115               10, 0, // offset to value #1 (i16)
3116               9, 0, // offset to value #2 (u8)
3117               4, 0, // offset to value #3 (f32)
3118               10, 0, // offset to vtable
3119               0, 0, // padding
3120               0, 0, 64, 64, // value #3 => 3.0 (float32)
3121               0, 2, // value #1 => 2 (u8)
3122               1, 0, // value #0 => 1 (int16)
3123         ]);
3124     }
3125 }
3126 
3127 #[cfg(test)]
3128 mod copy_clone_traits {
3129 
3130     use alloc::vec::Vec;
3131 
3132     #[test]
follow_types_implement_copy_and_clone()3133     fn follow_types_implement_copy_and_clone() {
3134         static_assertions::assert_impl_all!(flatbuffers::WIPOffset<u32>: Copy, Clone);
3135         static_assertions::assert_impl_all!(flatbuffers::WIPOffset<Vec<u32>>: Copy, Clone);
3136 
3137         static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<u32>: Copy, Clone);
3138         static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<Vec<u32>>: Copy, Clone);
3139 
3140         static_assertions::assert_impl_all!(flatbuffers::Vector<'static, u32>: Copy, Clone);
3141         static_assertions::assert_impl_all!(flatbuffers::Vector<'static, Vec<u32>>: Copy, Clone);
3142     }
3143 }
3144 
3145 #[cfg(test)]
3146 mod fully_qualified_name {
3147     #[test]
fully_qualified_name_generated()3148     fn fully_qualified_name_generated() {
3149         assert!(check_eq!(super::my_game::example::Monster::get_fully_qualified_name(), "MyGame.Example.Monster").is_ok());
3150         assert!(check_eq!(super::my_game::example_2::Monster::get_fully_qualified_name(), "MyGame.Example2.Monster").is_ok());
3151 
3152         assert!(check_eq!(super::my_game::example::Vec3::get_fully_qualified_name(), "MyGame.Example.Vec3").is_ok());
3153         assert!(check_eq!(super::my_game::example::Ability::get_fully_qualified_name(), "MyGame.Example.Ability").is_ok());
3154     }
3155 }
3156 
3157 // this is not technically a test, but we want to always keep this generated
3158 // file up-to-date, and the simplest way to do that is to make sure that when
3159 // tests are run, the file is generated.
3160 #[cfg(not(feature = "no_std"))]
3161 #[test]
write_example_wire_data_to_file()3162 fn write_example_wire_data_to_file() {
3163     let b = &mut flatbuffers::FlatBufferBuilder::new();
3164     create_serialized_example_with_generated_code(b);
3165 
3166     use ::std::io::Write;
3167     let mut f = std::fs::File::create("../monsterdata_rust_wire.mon").unwrap();
3168     f.write_all(b.finished_data()).unwrap();
3169 }
3170 
3171 #[cfg(not(feature = "no_std"))]
load_file(filename: &str) -> Result<Vec<u8>, std::io::Error>3172 fn load_file(filename: &str) -> Result<Vec<u8>, std::io::Error> {
3173     use std::io::Read;
3174     let mut f = std::fs::File::open(filename)?;
3175     let mut buf = Vec::new();
3176     f.read_to_end(&mut buf)?;
3177     Ok(buf)
3178 }
3179 
3180 #[test]
test_shared_strings()3181 fn test_shared_strings() {
3182     let mut builder = flatbuffers::FlatBufferBuilder::new();
3183     let offset1 = builder.create_shared_string("welcome to flatbuffers!!");
3184     let offset2 = builder.create_shared_string("welcome");
3185     let offset3 = builder.create_shared_string("welcome to flatbuffers!!");
3186     assert_ne!(offset2.value(), offset3.value());
3187     assert_eq!(offset1.value(), offset3.value());
3188     builder.reset();
3189     let offset4 = builder.create_shared_string("welcome");
3190     let offset5 = builder.create_shared_string("welcome to flatbuffers!!");
3191     assert_ne!(offset2.value(), offset4.value());
3192     assert_ne!(offset5.value(), offset1.value());
3193     builder.reset();
3194 
3195     // Checks if the shared string function would always work with
3196     // an object in between the writes
3197     let name = builder.create_shared_string("foo");
3198     let enemy = my_game::example::Monster::create(&mut builder, &my_game::example::MonsterArgs {
3199         name: Some(name),
3200         ..Default::default()
3201     });
3202     let secondary_name = builder.create_shared_string("foo");
3203     assert_eq!(name.value(), secondary_name.value());
3204 
3205     // Builds a new monster object and embeds enemy into it so we can verify
3206     // that shared strings are working.
3207     let args = my_game::example::MonsterArgs {
3208         name: Some(secondary_name),
3209         enemy: Some(enemy),
3210         testarrayofstring: Some(builder.create_vector(&[name, secondary_name])),
3211         ..Default::default()
3212     };
3213     // Building secondary monster
3214     let main_monster = my_game::example::Monster::create(&mut builder, &args);
3215     builder.finish(main_monster, None);
3216     let monster = my_game::example::root_as_monster(builder.finished_data()).unwrap();
3217 
3218     // Checks if the embedded object (Enemy) name is foo
3219     assert_eq!(monster.enemy().unwrap().name(), "foo");
3220     let string_vector = monster.testarrayofstring().unwrap();
3221     // Check if the vector will have the same string
3222     assert_eq!(string_vector.get(0), "foo");
3223     assert_eq!(string_vector.get(1), "foo");
3224 }
3225 
3226 }
3227