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