Squashed 'third_party/flatbuffers/' changes from acc9990ab..d6a8dbd26

d6a8dbd26 Experimental fix for failing oss-fuzz coverage build (#6259)
ed391e177 BREAKING: Rust flexbuffers serde human readable set to false (#6257)
a49531414 Update to flags in fuzzing-cmake file (#6256)
de1f0342c Remove _POSIX_C_SOURCE and _XOPEN_SOURCE definitions when compiling o… (#6205)
d0d51e2a5 flatc should support --binary --schema with optional scalar fields. (#6252)
33ab26017 Bump version of rules_go to 0.24.5 (#6234)
febb9d87c Union As Accessors for C# (#6251)
8778dc7c2 Resets buffer without deallocating current pointer (#6247)
aae376e9a Add GetBufferSpan() function to bufferbuilder (#6235)
0ff047148 Modernize android build and sample (#6229)
46a8c7e95 Added required-nested-flatbuffer to monster_test and fixed rust (#6236)
bc56c553e Notify based on Labelling issues and PR (#6241)
07d7cd78a Converted globs to use single quotes (#6240)
cdef70e24 More adjustments to the auto labeler (#6239)
9dd44df35 Updated Lua labeller glob (#6238)
c9b29d088 Support size-prefixed buffers and add tests for size-prefixed messages (#6232)
fba93e0ab Removes duplicate swift in labeler (#6228)
d1a545b1f Added more labels for auto labeler (#6227)
ea92a668d [C#] Optional Scalars (#6217)
6034de286 [Label Bot] Add Java and Kotlin support for the label bot (#6226)
b08b0a440 Implement `Debug` trait for Rust flatbuffers. (#6207)
17ae48dec [Label Bot] Adds some languages to labeler bot (#6222)
fc8097925 Auto Labeler Setup, Just C# for now (#6221)
55658f523 Auto Labeler Setup, Just C# for now (#6218)
14ecfe423 Updated comments and fixed a fundamental type error. (#6214)
a0182cdb1 optional scalars for ts/js (#6215)
0dfcc0a37 Adds NetTest.bat to run .NET Core tests on Windows (#6216)
f9a18ea63 [Java] Implement optional scalars (#6212)
c7586e85a Empties the sharedString map on reset on go and csharp (#6187)
914c64601 Removed C# references from java generator. Move annotations closer to definitions (#6204)
42d7c7997 Adds readable size to asserts in read functions (#6210)
e68e8d7de Refactor idl_gen_rust (#6206)
84809be7e Fix typo in flatbuffers::span declaration. (#6202)
1606fb637 Kotlin test optional enum (#6201)
fe8e3c7e5 Mass Refactoring to use `IsString` and other BASE_TYPE helpers (#6193)
8f6fa4b71 Updated SupportsAdvancedUnionFeatures to look out for string (#6190)
b46db38f5 [JS/TS] Rewrite flexbuffers JS to TS (#6148)
9fa1d2705 Rework enums in rust. (#6098)
a402b3aba idl_gen_json_schema Fix generation of arrays of enums (#6184)
0e1415b99 fix(go_test): remove deprecated grpc call (#6183)
5cd713710 Add generation of JSON Schema to library (#6165)
5be777e1d Bump junit from 4.12 to 4.13.1 in /grpc/tests (#6173)
a49d440ec Bump junit from 4.12 to 4.13.1 in /grpc (#6172)
4ec5e8db9 [C++] Add option to not generate direct copy methods. (#6166)
04bec23a3 Add Array initialization from struct constructor (#5865) (#6147)
77d57fd07 Cast to right type for reserved_ subtraction (#6167)
543c1bbeb Fixed rust nested flatbuffers for tables other than self (#6062)
cb971eece [C++] Fix -Wnarrowing and -Woverflow due to signed bitfields on G++ ARM (#6163)
7b9e61fcc [TS] GRPC  Implementation (#6141)
3359e3042 Moved C++ to optional_scalars2 and added some tests. (#6162)
187a4787f [Rust] Upgrade flatbuffers library to 2018 edition (#6159)
08943aa26 Flatbuffer C++ UnpackTo optimization for vectors of non-bool bytes. (#6154)
5975658eb Enables optional enums in swift (#6160)
5d3cf440e Updated Lobster test for optional bools/enums
8ec8322f0 Ruopt enum (#6156)
bbcc85fd4 Fix generation of C++ code with Optional<Enum> (#6155)
0bdf2fa15 [C#] Fix and improve project files (#6142)
2eedc769d possibility to create a vector from an iterator (#6135)
ab01ae162 flatc should output a warning, when an attribute is attached more than once (#6146)
689bfafa7 [Python/JS/TS] Codegen SizeOf method for structs (#6136)
641309a5b unix2dos on tests/FlatBuffers.Test/FlatBuffers.Core.Test.csproj (#6133)
52e362879 SpanT is available in .Net Standard 2.0. (#6137)
dca12522a Add static cast to avoid implicit double promotion. (#6132)
e0bbaa6f9 [C#]Change to ENABLE_SPAN_T that doesn't require UNSAFE_BYTEBUFFER. (#6073)
ab139d6be Revert "[C#] Fix and improve project files (#6116)" (#6130)
34d67b425 Minireflect fixed array (#6129)
96d5e3597 [JS/TS] fix flatbuffers default export (#6123)
eb686a86f Add missed file generated by optional_scalar.fbs (#6125)
750281630 [C#] Fix and improve project files (#6116)
fb4e1c34f Add CharToLower and CharToUpper into util.s (#6126)
8c67b5b12 Add support of Optional<T> scalars to C++ code generator (#6092)
6228b66d3 [Kotlin] Support for optional scalars. (#6115)
e1be8aaad Bump version for latest swift version (#6121)
94873e595 [JS/TS] Modernize TypeScript / JavaScript flatbuffers support (#6095)
b8e87fafe [JS] Add getFullyQualifiedName() (#6119)
f96d1ef74 [Java] allowing larger buffer sizes when growing a byte buffer (#6118)
89435303b [Swift] Migrates struct write APIS to write directly to the buffer (#6093)
c75ae2429 Optional-ness in reflection (#6097)
338944d3d Rename Nullable scalars to Optional scalars (#6112)
f5ab24bc4 Avoid memcpy call for empty vectors (#6111)
92a8c1a0f [JS] FlexBuffers Fix for wrong type of offset and length values (#6107)
6cea45dcd fix c# json serializer commandline argument docs (#6104)
fec58aa12 Fix for issue 6100: incorrect shrinking logic in ResizeContext() (#6102)
71aca81ff [JS] FlexBuffers Support (#5973)
04d87ffec [C++] Small refactoring of the C++ code generator (#6091)
bb25956f0 Wrap verify file id condition in Check call (#6085)
49f4948f0 + Add `removable-media` plug to the snapcraft config (#6083)
eeacc53d2 Adds proper access types for swift object api & flatbuffers & grpc (#6081)
f3003e08d [Lobster] missed a test
d713a0084 [CMake] enabled multi-core builds in VS projects
77f966f89 [Lobster] optional scalars support
e86d5b8e9 [Kotlin] Attach JvmStatic annotation to each method in companion object (#6052)
db2aa9b4e [C#] Cleaned up .NET testing script for Mono (#6016)
63cc0eec4 Adds a serialize helper function to native table (#6059)
c30a87de6 [TS] Fix four bugs with imported types in TypeScript. (#6054)
a0fb30575 [Swift] Append namespace for Swift Grpc implementation (#6049)
77c18c1d6 export a __version__ variable for python module (#5309)
f1f23d08e adding fb import when no other imports are present (#6030)
f1025b284 [Feature] Checks for Nullable strings (#6050)
5d052f4e5 [Swift] RFC: Switch Swift namespace from public enum to ordinary concat with _ (#6045)
18b015d25 Rust codegen improvements and lint fixes (#6046)
d76e93f27 adds code gen for optional scalars in swift (#6038)
82fac326c [C++] Fix compiler error from deleted assignment operator (#6036) (#6047)
043b52bd4 Optional Scalars support for Rust (#6034)
c8fa0afdf Allow to run cpp tests under grpc/tests/ using bazel. (#6040)
6d0aae73c Fix git command executed in wrong folder when doing cmake superbuild (#6039)
ff1b73128 [Swift] Optional Scalars Preparation (#6028)
2e48c8dd3 tests: Check for both quiet and signaling NaN on mipsel/hppa (#6029)
6942704f2 support deprecated flag in json schema (#6022)
9ecd2e16c Flatc parser support for nullable scalars (#6026)
33e2d8079 [Dart] Generate constant values map for enums (#6025)
969d0f7a6 Using proper symbol name for reexport (#6021)
515a4052a Silence false positive "-Wstringop-overflow" on GCC 10.0 to 11.0 (#6020)
36fbe6f13 Updated FB import (#6019)
b69fc8cc9 [Java] Add support for shared strings on FlatBufferBuilder. (#6012)
ab6af18d9 Not using non-existent create method for obj api (#6015)
37a5dee10 Code cleanup + updates test and readme (#6004)
8a721f69a Serde with bytes maps to Blob (#6009)
e810635ea [Swift] FlatBuffers createMonster method doesn't treat struct properly (#5992)
4995e1527 Manage grpc dependency in Bazel's WORKSPACE file. (#5995)
60b6066fe Add warning to schema parser if field name is not snake_case. (#6005)
35d45cac7 [Rust] Flexbuffers dependency cleanup and fixes (#5998)
165a6e3d1 Re-added Evolution Schema Code Generation Command (#5999)
13d3fb2ea Fix RPM install conflict (#6003)
d64078eb2 [Swift] Initialize memory when clear ByteBuffer (#5982)
ca1190a3d [TS] Use proper TypedArray in create*Vector (#5991)
7571b2ac5 [C++] Updates real_path to be truly portable (#5787)
e5a8f76a4 [C++] Generate default member initializers for >= C++11 (#5989)
413bb9b55 [Kotlin] Fix Access to union of vector element (#5994)
f35184aef [Swift] Add parsing from unowned UnsafeMutableRawPointer for ByteBuffer (#5981)
b124b7625 Removed requirement that enums be declared in ascending order. (#5887)
0ec7600c6 Do not remove the last digit from float values (#5974)
14baf45c9 Mark GetBufferMinAlignment() const (#5985)
9abb2ec2c TypeScript/JavaScript docs improvements (#5984)
2e57d80b1 [Swift] Internal library improvements (#5965)
cfc7753a4 [Doc] Added missing letters to compiler options (#5976)
12ddc8a92 Rust Flexbuffers Documentation update (#5979)
24ad35709 [docs] typo: updates monsterdata.json to be valid json (#5978)
cc44a4442 [idl_parser] Mark typefield as deprecated (#5958)
9ab4a5c0e Deleted old stale bot
6682cfe87 Increased Operations per run in stale.yml
64922904b Adding Stale Action to clean up PR and Issues
8e505cb67 [C++] Fixed/Enabled --cpp-ptr-type std::shared_ptr [#5813] (#5959)
a28357d7a Propagate boolean default values from proto to fbs (#5964)
7cb4762a6 [Swift] Improving reallocation time by using memcpy and moving reallocation code to storage (#5960)
4e45f7c9e Fix error in SimpleQSort (#5955)
7ac026405 fix error on GRPC Python - ignore namespace tree if not specified (#5862) (#5922)
108e981db Required is now implemented in swift (#5952)
94a78e385 Fixed: Access violation and ASAN/UNSAN failures with sorted tables
53fb453e0 [rust] Add FlatBufferBuilder::force_defaults API (#5946)
17c1f35fa [FlexBuffer][Java] ReadWriteBuf and ReadBuf interface public (#5948)
2eaf57778 [Java] Grow ArrayReadWriteBuf enough to match requested capacity. (#5921)
666800da3 Adds bool support in structs + updates grpc support + CI upgrades (#5943)
38ed69eb3 fixed mutating inline values (#5942)
d026e6f07 Add static asserts to ensure that reflection API arrays are kept in sync (#5934)
988164f6e [C++] Got rid of memset's in constructors (#5938)
7179a5a8b General Codebase clean up (#5939)
a0da0c08c Add GetStringView like GetString, GetCstring (#5937)
ac203b209 [C#] Add file identifier to ObjectAPI Serialization Utility. (#5920)
8dd1bf25b not creating creation methods when using structs (#5919)
5aa443d98 [Dart] Adding FlexBuffers support (#5853)
0fa087657 [Dart] Getting tests/DartTest.sh to work on master. (#5915)
424a473e1 Schema parser: prohibit declaration of an array of pointers inside structs (#5907)
c3faa8346 Fix Cargo.toml dependencies (#5911)
91399ad05 fix union type names (#5902)
32782e4ad Update Rust Flexbuffers metadata before publishing (#5905)
e7f3b1690 [TS] Make Obj-API work with --short-names (#5898)
12ed1fe4a fixed invalid imports with --gen-all (#5895)
85ee4df7a [C#] Thread safe reads of Double and Float values from a ByteBuffer (#5900)
de89bd193 Implement flexbuffers in python (#5880)
8be05f6bd Rust Flexbuffers (#5669)
870ecbc09 [swift] Moves code to use VTablesStorage (#5888)
c2da8d5d8 [Java][FlexBuffers] Make FlexBuffersBuilder reusable by adding clear() (#5889) (#5890)
e84cbff67 Align package name to FindFlatBuffers.cmake (#5899)
f94e6c84e Small tutorial improvements - documentation only (#5894)
f12cca8bc Attempt at adding Github Actions CI
7e4124d6e Handle git program or .git folder absence (#5878)
a875d247a only add native_include_files if object based api is enabled (#5886)
6e9f5d981 Respect shared attribute in Parser (#5885)
ff1c78233 include/flatbuffers: typo fixes in comments (#5884)
2e9a19673 Updates swift docs for package management (#5883)
e3cb07d32 [Rust] idl_gen_rust.cpp: (Option/required-aware codegen for unions) (#5850)
712866d57 Propagate use_string_pooling in CopyTable (#5879)
44c919a9e Not using reexports with --gen-all (#5873)
99aa1ef21 Added INCLUDE_PREFIX option for flatbuffers_generate_headers (#5866)
40ba170c9 Fixed text in internals doc that implied structs can be root
cb4d0f72e [Swift] Object API support  (#5826)
003e16405 [TS] Add Obj API (#5788)
21cf300f4 fix cpp usage markdown error (#5845)
9655e12d6 Upgraded swift implementation for grpc (#5843)
fb96fadc2 [C#] Fix nested structs and arrays in Object API (#5765)
408f11fbd [ts] Fix empty source/dest namespaces when reexporting. (#5841)
a83caf591 Improves performance for the swift library by using structs + a storage class (#5835)
925fab6b1 [Java][FlexBuffers] Optimize Map access (#5735)
d9fecc332 [CMake] : Add precompiled header support with FLATBUFFERS_ENABLE_PCH (#5827)
e9d453240 Added flatbuffers_generate_headers and flatbuffers_generate_binary_files cmake functions. (#5830)
c37c989ed Correct calculation of vector element size (#5831)
6b271b7ec Fix Clang-trunk warnings about special members deprecated in C++20. (#5829)
90f3b8e8c Fix `float_constant` definition in './doc/Grammar.md` (#5828)
3af735934 [csharp] flatc should generate a 'Create…' method for tables with struct field… (#5818)
c4231c3cb Updated doxyfile - added missing files (#5824)
9657df184 Update Grammar.md (#5820)
97ffc590e Include CPack only when explictly packaging (#5817)
8b52af65b [C++] Add max_depth and max_tables parameters to reflection::Verify (#5815)
9b034eee1 Fix interpretation of 'nan(number)' by the idl_parser (#5810)
3e9ac3cff [Scripts] Adds swift to generated code (#5806)
697147a2e updated maven build files
6df40a247 pre-tag version bump for 1.12
0dba63909 Removes the inner loop in the endtable check written tables (#5803)
0e3fdd0ee Escape characters in jsonschema descriptions (#5644)
45a2b07cb Remove `noexcept` qualifier copy-ctor of `union` type (#5800) (#5802)
d10c16314 Replace 'assert' by 'FLATBUFFERS_ASSERT' inside idl_parser.cpp (#5799)
35abb7f89 Add non-nullable modifier to return type of functions never returning null (#5797)
9954e09ab [C++] Generate code for vector force_align attribute. (#5796)
95a21327f rust: pub export the VectorIter type (#5736)
89b6183ee Fix Python min alignment
5a98d65e8 [Rust] Add gen-name-strings for Rust (#5757)
f73d205bc Removed assert that wasn't backwards compatible.
7c37abe92 [C#] add ObjectAPI Serialization Utility (#5785)
4749e77b0 Fixed docs on how to obtain parser error.
6ff189841 Added --filename-suffix and --filename-ext to flatc (#5778)
c9a30c9ca Fixed refractoring issue in reflection/generate_code.sh. Also, mv deletes the original file, so I don't need to clean it up manually in that case. (#5777)
8c02d17be Skip writing reflection_generated.h if not changed (#5776)
34305c4ce [Swift] Adds GRPC to Swift (#5758)
cd88e6b2a [Java][FlexBuffers] Abstract buffer access from ByteBuffer (#5743)
3ec7a53c6 Adds cocoapods and a readme of how to get the package (#5771)
6d44cede7 [snap] Fix versioning (#5727)
cc08c0835 [Python] Fixed potential allignment issue (#5768)
54f8b787c Fix memory leak on cpp object api (#5761)
17557f913 [Python] Fixed issue #5499 (#5764)
d54af8cd4 [C++] Use strong enum type for vectors when scoped-enums is on. (#5750)
173e10fdf [C#] support Json Serialization (#5752)
8f56990f6 FlexBuffers: C++: scalar-only typed vectors were not aligned.
6400c9b05 Bump Rust port to 0.6.1 (#5747)
7418d8587 [C#] support Object API (#5710)
c580fa284 Adds min and max, comments, and all of swift's keywords + fix docs (#5737)
f2a127230 Use VS 2017 and 2019 on CI, fix cast issue in dart_idl (#5740)
316d7c208 Creates a flatbuffers validation function + small fix (#5725)
47026ea6b Added the code to embed the binary schema to the source (--bfbs-gen-embed). (#5701)
3f677f241 [Java][FlexBuffers] Deprecate typed vector strings due to design flaw (#5722)
a593a11e5 [Go] Implements a SharedStrings function (#5733)
7cdfc8475 [Swift] Fix padding function overflow when bufSize is 0 (#5721)
bab2b0db4 Add vcpkg installation instructions (#5732)
89418eb84 [Dart] Fix deprecated field support, inf/nan (#5724)
9cadf05d8 [typescript] Size-prefixed root accessors not taking into account size prefix (#5717)
6da1cf79d [rust] Add use declarations to Rust-generated bindings for imported FB definitions (#5645)
bee1df96d [Go] Replace references to hardcoded ”Monster" etc with idiomatic go wherever possible (#5716)
01189d7ed [C++] Fix for printing of enum in case output_enum_identifiers=1. (#5706)
c4b2b0a25 [Swift] Support create long string (#5709)
a4b2884e4 Added create function for swift (#5707)
04d80f255 [Swift] Swift implementation 🎉🎉 (#5603)
55686100a Changed direct calls to strtod to use StringToNumber
718351831 Document JSON compatibility guarantees. (#5704)
d1b34f0f2 Add CMake 'generated_code' target to simplify resolution of build dependencies (#5697)
21b706196 (Optionally) add an additional suffix namespace to generated fbs files. (#5698)
35daaf83d [Java] Replace Table.UTF8_CHARSET with StandardCharsets.UTF_8 (#5696)
3b458f7a1 Rust: Temporarily disable 2 endianness unit tests (#5695)
a5d9d0f7d [C++17] Add Traits class for Tables and Factory function within it. (#5678)
3cd9b6434 Removed code_generators.cpp from library targets
355dfd48d [rust] Make enum names public (#5690)
bcd58a159 Correct inverted logic around include prefixes. (#5689)
a2c12900a Optimize Pack method using numpy (#5662)
901b89e73 [C++] Add Builder and Table typedefs (#5685)
31f879908 Minor doc updates: FlexBuffers C#, Discord, CppUsage.
8023d99e2 Upgrade rules_go (#5684)
b4154405d Fix --incompatible_load_cc_rules_from_bzl (#5683)
04c17c7a7 Add support for absl::string_view when available (#5682)
62ec7d52c [Bazel] Add support for compatible_with and restricted_to (#5681)
7de668053 CI: New Docker tests for Python with numpy (#5677)
3a70e0b30 Fixed struct initialization error on older versions of C#
9b1320135 Fixed warnings in FlexBuffers.java
5e3916050 Fixed out of date licenses on gRPC Python files.
c95755051 Removed test proto output.
44bf71988 Add flatc '--cpp_std' switch (#5656)
3e8f15df9 Fix for FlexBuffers FBT_VECTOR_STRING size bit-width.
602721a73 Added Check to VerifyAlignment (#5675)
13c05f4da Improve import handling for proto conversion (#5673)
ce3a1c43a [Dart] Fix prepare space for writeListInt64 and writeListUint64 (#5654)
aa75e5734 Make Rust constants public (#5659)
2790fee25 Add namespace qualification to union types (#5666)
eddebec1b Bugfix for Rust generation of union fields named with language keywords (#5592)
030fee36a wrap multiple statements in do {} while(!IsConstTrue(true)) (#5655)
f9724d1bd [gRPC] Uncomment MessageBuilder (#5658)
b20801ca4 Supress unsigned-integer-overflow for PaddingBytes (#5647)
a8e800bd7 Add --force-empty-vectors option (#5653)
d7530ae96 Fixed enum min/max values not properly escaped.
99d11e279 Split Bazel targets into multiple packages (#5640)
4fd8eb214 Remove a static_assert (#5643)
65f870357 Flatbuffers Python Object API (#5616)
75823cc27 [Clang 10]: definition of implicit copy constructor for 'TableKeyComparatoris deprecated #5649 (#5650)
58e279244 [docs]: add missing semicolon (#5648)
3c964e10a [GO] Fix support for enums with underscores and Unions with imported members (#5600)
c3c32ec94 Fix ambiguity of a type deduction in TEST_EQ macro if arguments have `enum class` type. (#5630)
075e8d676 Simplify declarations of x-macro FLATBUFFERS_TD (#5638)
bcf1bd5c9 read vtable size through ReadScalar() (#5636)
136d75fa6 Changed null checks in test. Removed verifier pointer usage (#5634)
091fa1fd1 Add testing of C++ with sanitizers (CI-Docker) (#5631)
ff3781dc2 add namespace prefix in FLATBUFFERS_MAX_BUFFER_SIZE (#5629)
6beb9f49c Support for python grpc - continuing the work from the pull request #4270 #4705 (#5613)
80988ea86 Removed idl_gen_general.cpp and move contents to code_generators.cpp (#5625)
0f2ff7eaa Lua cleanup (#5624)
dda095023 [C++] Adds basic schema evolution tests (#5611)
adbcbba5d [C++, C#, Java] Separated C# and Java generators into their own classes (#5618)
cbbd6aca0 add check for root_type specified for json schema generation (#5622)
405c64e07 [Rust] Bump smallvec version to 1.0 (#5621)
42c08cbca Ran src/clang-format-all.sh (#5617)
33d5dd9bd Improved pull request & clang-format instructions.
105dd528e Change monster_extra generation to use flatbuffers::unique_ptr (#5612)
f0f0efe7b [C++] Refactor to conform to Google C++ style guide (#5608)
e837d5a29 Fixed deprecated method in GRPC Java test.
9834ee978 Fixed Apache license not using canonical version.
44b2ab087 include/flatbuffers/base.h: fix no_sanitize issue with old clang (#5610)
46ae3f80a [C++, Java, C#, TypeScript, JavaScript] Skip generation of mutable union types (#5599)
7b38aa71e flatbuffers.h: fix documentation warning (#5607)
661bedd83 Add Lua FlatbufferBuilder Clean() method to enable reuseable builders (#5606)
8526e12d7 [Kotlin] Fix union vector accessor after change in Java API (#5605)
3c7b660d6 [flatc] Remove an always true condition for flexbuffers (#5604)
964365ba6 [Go] Add UnPackTo functions (#5598)
32254b7ac [Go] Object API support (#5339)
521e255ad Rust: Add idiomatic iterator for Vector type (#5579)
1b85292fd Fix typos in comments (#5590)
480815447 C++ verifier for evolved union fields should return true (#5586)
8d5e424c6 Add ByteBuffer copy for vector of bytes in Java (#5587)
b4774d235 Rust: Fix Copy and Clone impls for a few generic types (#5577)
26f238c24 Add `--clean-first` to the cmake-build command (travis) (#5574)
e93c8c46e Fix Follow implementation for bool (#5554)
e21516b9d Fix issue #5557 (#5573)
fbc11e8ae Avoid intentional unsigned integer overflow getting caught by sanitizers (#5572)
e9d29c21a Python: Add forceDefaults opt to python Builder (#5564)
8bfafc76d Java: Don't annotate vector-of-tables item getters with @nullable. (#5562)
df3e8bf4a Fixed warnings generated by recent JSON sorting feature.
5665cfe49 [Java] byte buffer factory returned buffer capcity is used instead of the requested size (#5558)
5797540ed #5544 Fix of Array of table is not sorted if Create<type>Direct() is used (#5546)
7f1af7cb0 Fix build with gcc version 7.4.0 (#5570)
32f47ad24 Fixed JSON parser not sorting vectors of tables/structs with key.
842f672ba [FlexBuffers][Java] Cache size of Sized objects in FlexBuffers (#5551)
d4cae0a62 Fix issue #5542 (#5543)
f1147f65b Fixed Android STLPort related error.
69d3fec48 Fix namespaced struct/field name collision detection (#5540) (#5545)
cfb4ecf6f [flac] Add FlexBuffers option for generating data (#5519)
a92039687 Update Rust versions under test from 1.30.1 to 1.37.0 (#5538)
625338d09 Adds XOPEN_SOURCE for PATH_MAX and POSIX 1993 for stat (#5529)
3f8ce99c5 [FlexBuffers][Java] Add override Key::toString (#5533)
0798b7b69 [FlexBuffers][Java] Fix wrong access to a string using Reference::asString(). (#5532)
cbdf82e2f Fix Mutate() methods of Array<scalar/struct> (override 5508) (#5526)
e365c502f Java: Added access object for vector of struct and vector of tables. (#5233)
97f3aa917 Fixed DetachedBuffer self move assignment (#5521)
2f5bb2eec Fix buildifier warnings found in new bazel (#5517)
917687c7a Fixed Reflection Verifier not handling vectors of unions.
f9277e691 Fixed GenerateText not handling vectors of unions.
2706381ee Add element size parameter to __vector_as_arraysegment [c#] (#5512)
b5560fcd5 [Java][FlexBuffers] Improve documentation for FlexBuffers in Java. (#5506)
782b865c5 Annotate getters with @Pure when --java-checkerframework is specified. (#5510)
3bfc86eaf [Dart]fix: segment fault with empty namespace when generating dart file (#5507)
c0282873f Rust: Fixed cargo clippy on non-generated code (#5485)
4b870aca9 [Javascript] Fix syntax error for signed enum (#5503)
d0e3870c0 [C#] Fix retrieving enumeration vectors as arrays (#5457)
fb25eb87f Doc typo fixes (#5505)
cb35d3a0e Use all of the available space in the buffer returned by ByteBufferFactory to allow the factory to keep a pool of larger than initialsize sized buffers. (#5500)
8e6cabb31 [FlexBuffers][Java] Implementation of FlexBuffers API (#5476)
bd31dd242 Clarified value reuse in FlexBuffers
65b67d213 Fixed test build invocation of arrays_test.fbs
1fbb71132 FlexBuffers: allow any values to be shared.
cd75a3658 Android: remove app_dummy() calls
ec6b0bf29 Fixed STLPort Android compile error
c11b5d744 [bugfix]flexbuffers isvector bugfix (#5488)
4525c91be Fix incorrect padding in arrays of structs (Issue #5484) (#5491)
b97b342f5 Fixed missing generated code.
c1058a903 C++ IDL generation adds superfluous semicolon in GenTablePost, causing (#5483)
303044934 [go]add Name() for ForceCodec  interface (#5486)
a2485d4ec reflection: check for valid union enum value during object verification (#5475)
a20e71ac9 has_method support for primitive fields in java runtime. Changed: idl.h, FlatBufferBuilder.java ,  idl_gen_general.cpp, idl_parser.cpp, flatc.cpp (#5468)

Change-Id: I836f4b43e6818bb16425a87899e6234ac86242aa
git-subtree-dir: third_party/flatbuffers
git-subtree-split: d6a8dbd26ff08a8868e0d0c1b4b67d31b40e4a7f
diff --git a/tests/rust_usage_test/Cargo.toml b/tests/rust_usage_test/Cargo.toml
index 490d6d2..664396d 100644
--- a/tests/rust_usage_test/Cargo.toml
+++ b/tests/rust_usage_test/Cargo.toml
@@ -1,26 +1,51 @@
 [package]
 name = "rust_usage_test"
 version = "0.1.0"
-authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
+authors = ["Robert Winslow <hello@rwinslow.com>",
+           "Casper Neo <cneo@google.com>",
+           "FlatBuffers Maintainers"]
 
 [dependencies]
 flatbuffers = { path = "../../rust/flatbuffers" }
+flexbuffers = { path = "../../rust/flexbuffers" }
+serde_derive = "1.0"
+serde = "1.0"
+serde_bytes = "0.11"
 
 [[bin]]
 name = "monster_example"
 path = "bin/monster_example.rs"
 
 [[bin]]
-name = "alloc_check"
-path = "bin/alloc_check.rs"
+name = "flatbuffers_alloc_check"
+path = "bin/flatbuffers_alloc_check.rs"
+
+[[bin]]
+name = "flexbuffers_alloc_check"
+path = "bin/flexbuffers_alloc_check.rs"
+
+[[bin]]
+name = "sample_flexbuffers"
+path = "../../samples/sample_flexbuffers.rs"
+
+[[bin]]
+name = "sample_flexbuffers_serde"
+path = "../../samples/sample_flexbuffers_serde.rs"
+
+[[bin]]
+name = "sample_flatbuffers"
+path = "../../samples/sample_binary.rs"
 
 
 [dev-dependencies]
 quickcheck = "0.6"
 # TODO(rw): look into moving to criterion.rs
 bencher = "0.1.5"
+static_assertions = "1.0.0"
+rand = "*"
+quickcheck_derive = "*"
 
 [[bench]]
 # setup for bencher
-name = "flatbuffers_benchmarks"
+name = "benchmarks"
 harness = false
diff --git a/tests/rust_usage_test/benches/benchmarks.rs b/tests/rust_usage_test/benches/benchmarks.rs
new file mode 100644
index 0000000..bfe63b6
--- /dev/null
+++ b/tests/rust_usage_test/benches/benchmarks.rs
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#[macro_use]
+extern crate bencher;
+extern crate flatbuffers;
+extern crate flexbuffers;
+
+mod flatbuffers_benchmarks;
+mod flexbuffers_benchmarks;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../monster_test_generated.rs"]
+mod monster_test_generated;
+pub use monster_test_generated::my_game;
+
+benchmark_main!(
+    flatbuffers_benchmarks::benches,
+    flexbuffers_benchmarks::benches
+);
diff --git a/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs b/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
index 2c6be1f..ee6d81d 100644
--- a/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
+++ b/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
@@ -14,11 +14,15 @@
  * limitations under the License.
  */
 
-#[macro_use]
-extern crate bencher;
 use bencher::Bencher;
 
-extern crate flatbuffers;
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
 
 #[allow(dead_code, unused_imports)]
 #[path = "../../monster_test_generated.rs"]
@@ -55,42 +59,69 @@
 }
 
 #[inline(always)]
-fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder, finish: bool) -> usize{
+fn create_serialized_example_with_generated_code(
+    builder: &mut flatbuffers::FlatBufferBuilder,
+    finish: bool,
+) -> usize {
     let s0 = builder.create_string("test1");
     let s1 = builder.create_string("test2");
     let t0_name = builder.create_string("Barney");
     let t1_name = builder.create_string("Fred");
     let t2_name = builder.create_string("Wilma");
-    let t0 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
-        hp: 1000,
-        name: Some(t0_name),
-        ..Default::default()
-    });
-    let t1 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
-        name: Some(t1_name),
-        ..Default::default()
-    });
-    let t2 = my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
-        name: Some(t2_name),
-        ..Default::default()
-    });
+    let t0 = my_game::example::Monster::create(
+        builder,
+        &my_game::example::MonsterArgs {
+            hp: 1000,
+            name: Some(t0_name),
+            ..Default::default()
+        },
+    );
+    let t1 = my_game::example::Monster::create(
+        builder,
+        &my_game::example::MonsterArgs {
+            name: Some(t1_name),
+            ..Default::default()
+        },
+    );
+    let t2 = my_game::example::Monster::create(
+        builder,
+        &my_game::example::MonsterArgs {
+            name: Some(t2_name),
+            ..Default::default()
+        },
+    );
     let mon = {
         let name = builder.create_string("MyMonster");
         let fred_name = builder.create_string("Fred");
         let inventory = builder.create_vector_direct(&[0u8, 1, 2, 3, 4]);
-        let test4 = builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
-                                                   my_game::example::Test::new(30, 40)]);
-        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));
-        let args = my_game::example::MonsterArgs{
+        let test4 = builder.create_vector_direct(&[
+            my_game::example::Test::new(10, 20),
+            my_game::example::Test::new(30, 40),
+        ]);
+        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),
+        );
+        let args = my_game::example::MonsterArgs {
             hp: 80,
             mana: 150,
             name: Some(name),
             pos: Some(&pos),
             test_type: my_game::example::Any::Monster,
-            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
-                name: Some(fred_name),
-                ..Default::default()
-            }).as_union_value()),
+            test: Some(
+                my_game::example::Monster::create(
+                    builder,
+                    &my_game::example::MonsterArgs {
+                        name: Some(fred_name),
+                        ..Default::default()
+                    },
+                )
+                .as_union_value(),
+            ),
             inventory: Some(inventory),
             test4: Some(test4),
             testarrayofstring: Some(builder.create_vector(&[s0, s1])),
@@ -147,7 +178,7 @@
 }
 
 fn create_string_10(bench: &mut Bencher) {
-    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
     let mut i = 0;
     bench.iter(|| {
         builder.create_string("foobarbaz"); // zero-terminated -> 10 bytes
@@ -162,7 +193,7 @@
 }
 
 fn create_string_100(bench: &mut Bencher) {
-    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
     let s_owned = (0..99).map(|_| "x").collect::<String>();
     let s: &str = &s_owned;
 
@@ -180,7 +211,7 @@
 }
 
 fn create_byte_vector_100_naive(bench: &mut Bencher) {
-    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
     let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
     let v: &[u8] = &v_owned;
 
@@ -198,7 +229,7 @@
 }
 
 fn create_byte_vector_100_optimal(bench: &mut Bencher) {
-    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1<<20);
+    let builder = &mut flatbuffers::FlatBufferBuilder::new_with_capacity(1 << 20);
     let v_owned = (0u8..100).map(|i| i).collect::<Vec<u8>>();
     let v: &[u8] = &v_owned;
 
@@ -215,5 +246,12 @@
     bench.bytes = v.len() as u64;
 }
 
-benchmark_group!(benches, create_byte_vector_100_naive, create_byte_vector_100_optimal, traverse_canonical_buffer, create_canonical_buffer_then_reset, create_string_10, create_string_100);
-benchmark_main!(benches);
+benchmark_group!(
+    benches,
+    create_byte_vector_100_naive,
+    create_byte_vector_100_optimal,
+    traverse_canonical_buffer,
+    create_canonical_buffer_then_reset,
+    create_string_10,
+    create_string_100
+);
diff --git a/tests/rust_usage_test/benches/flexbuffers_benchmarks.rs b/tests/rust_usage_test/benches/flexbuffers_benchmarks.rs
new file mode 100644
index 0000000..1e9c516
--- /dev/null
+++ b/tests/rust_usage_test/benches/flexbuffers_benchmarks.rs
@@ -0,0 +1,295 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use bencher::Bencher;
+use flexbuffers::*;
+
+fn push_vec_u64_to_map(b: &mut Bencher) {
+    let va = vec![u64::max_value() - 10; 512];
+    let vb = vec![u64::max_value() - 20; 512];
+    let vc = vec![u64::max_value() - 30; 512];
+    let mut n = 0;
+
+    b.iter(|| {
+        let mut fxb = Builder::default();
+        let mut m = fxb.start_map();
+        let mut ma = m.start_vector("a");
+        for &a in va.iter() {
+            ma.push(a);
+        }
+        ma.end_vector();
+        let mut mb = m.start_vector("b");
+        for &b in vb.iter() {
+            mb.push(b);
+        }
+        mb.end_vector();
+        let mut mc = m.start_vector("c");
+        for &c in vc.iter() {
+            mc.push(c);
+        }
+        mc.end_vector();
+        m.end_map();
+        n = fxb.view().len();
+    });
+    b.bytes = n as u64;
+}
+fn push_vec_u64_to_map_reused(b: &mut Bencher) {
+    let va = vec![u64::max_value() - 10; 512];
+    let vb = vec![u64::max_value() - 20; 512];
+    let vc = vec![u64::max_value() - 30; 512];
+    let mut fxb = Builder::default();
+    let mut n = 0;
+    let mut go = || {
+        let mut m = fxb.start_map();
+        let mut ma = m.start_vector("a");
+        for &a in va.iter() {
+            ma.push(a);
+        }
+        ma.end_vector();
+        let mut mb = m.start_vector("b");
+        for &b in vb.iter() {
+            mb.push(b);
+        }
+        mb.end_vector();
+        let mut mc = m.start_vector("c");
+        for &c in vc.iter() {
+            mc.push(c);
+        }
+        mc.end_vector();
+        m.end_map();
+        n = fxb.view().len();
+    };
+    go(); // warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+fn push_vec_u64_to_map_direct(b: &mut Bencher) {
+    let va = vec![u64::max_value() - 10; 512];
+    let vb = vec![u64::max_value() - 20; 512];
+    let vc = vec![u64::max_value() - 30; 512];
+    let mut n = 0;
+
+    b.iter(|| {
+        let mut fxb = Builder::default();
+        let mut m = fxb.start_map();
+        m.push("a", &va);
+        m.push("b", &vb);
+        m.push("c", &vc);
+        m.end_map();
+        n = fxb.view().len();
+    });
+    b.bytes = n as u64;
+}
+fn push_vec_u64_to_map_direct_reused(b: &mut Bencher) {
+    let va = vec![u64::max_value() - 10; 512];
+    let vb = vec![u64::max_value() - 20; 512];
+    let vc = vec![u64::max_value() - 30; 512];
+    let mut n = 0;
+    let mut fxb = Builder::default();
+    let mut go = || {
+        let mut m = fxb.start_map();
+        m.push("a", &va);
+        m.push("b", &vb);
+        m.push("c", &vc);
+        m.end_map();
+        n = fxb.view().len();
+    };
+    go(); // warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+
+fn push_vec_without_indirect(b: &mut Bencher) {
+    let mut builder = Builder::default();
+    let mut n = 0;
+    let mut go = || {
+        let mut b = builder.start_vector();
+        for i in 0..1024u16 {
+            b.push(i);
+        }
+        b.push(i64::max_value());
+        b.end_vector();
+        n = builder.view().len();
+    };
+    go(); // warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+// This isn't actually faster than the alternative but it is a lot smaller.
+// Based on the above benchmarks a lot of time is stuck in the `values` stack.
+fn push_vec_with_indirect(b: &mut Bencher) {
+    let mut builder = Builder::default();
+    let mut n = 0;
+    let mut go = || {
+        let mut b = builder.start_vector();
+        for i in 0..1024u16 {
+            b.push(i);
+        }
+        b.push(IndirectInt(i64::max_value()));
+        b.end_vector();
+        n = builder.view().len();
+    };
+    go(); // warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+
+fn example_map<'a>(m: &mut MapBuilder<'a>) {
+    m.push("some_ints", &[256; 5]);
+    m.push("some_uints", &[256u16; 5]);
+    m.push("some_floats", &[256f32; 5]);
+    m.push("some_strings", "muahahahahaha");
+}
+fn hundred_maps(b: &mut Bencher) {
+    let mut builder = Builder::default();
+    let mut n = 0;
+    let mut go = || {
+        let mut v = builder.start_vector();
+        for _ in 0..100 {
+            example_map(&mut v.start_map());
+        }
+        v.end_vector();
+        n = builder.view().len();
+    };
+    go(); // Warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+fn hundred_maps_pooled(b: &mut Bencher) {
+    let mut builder = Builder::default();
+    let mut n = 0;
+    let mut go = || {
+        let mut v = builder.start_vector();
+        for _ in 0..100 {
+            example_map(&mut v.start_map());
+        }
+        v.end_vector();
+        n = builder.view().len();
+    };
+    go(); // Warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+fn make_monster(mut monster: MapBuilder) {
+    monster.push("type", "great orc");
+    monster.push("age", 100u8);
+    monster.push("name", "Mr. Orc");
+    monster.push("coins", &[1, 25, 50, 100, 250]);
+    monster.push("color", &[255u8, 0, 0, 0]);
+    {
+        let mut weapons = monster.start_vector("weapons");
+        {
+            let mut hammer = weapons.start_map();
+            hammer.push("name", "hammer");
+            hammer.push("damage type", "crush");
+            hammer.push("damage", 20);
+        }
+        {
+            let mut axe = weapons.start_map();
+            axe.push("name", "Great Axe");
+            axe.push("damage type", "slash");
+            axe.push("damage", 30);
+        }
+    }
+    {
+        let mut sounds = monster.start_vector("sounds");
+        sounds.push("grr");
+        sounds.push("rawr");
+        sounds.push("muahaha");
+    }
+}
+fn serialize_monsters(b: &mut Bencher) {
+    let mut builder = Builder::default();
+    let mut n = 0;
+    let mut go = || {
+        let mut monsters = builder.start_vector();
+        for _ in 0..100 {
+            make_monster(monsters.start_map())
+        }
+        monsters.end_vector();
+        n = builder.view().len();
+    };
+    go(); // Warm up allocations.
+    b.iter(go);
+    b.bytes = n as u64;
+}
+fn validate_monster(r: MapReader) {
+    assert_eq!(r.idx("type").as_str(), "great orc");
+    assert_eq!(r.idx("age").as_u8(), 100);
+    assert_eq!(r.idx("name").as_str(), "Mr. Orc");
+    assert!(r
+        .idx("coins")
+        .as_vector()
+        .iter()
+        .map(|c| c.as_i16())
+        .eq([1, 25, 50, 100, 250].iter().cloned()));
+    assert!(r
+        .idx("color")
+        .as_vector()
+        .iter()
+        .map(|c| c.as_u8())
+        .eq([255, 0, 0, 0].iter().cloned()));
+
+    let weapons = r.idx("weapons").as_vector();
+    assert_eq!(weapons.len(), 2);
+
+    let hammer = weapons.idx(0).as_map();
+    assert_eq!(hammer.idx("name").as_str(), "hammer");
+    assert_eq!(hammer.idx("damage type").as_str(), "crush");
+    assert_eq!(hammer.idx("damage").as_u64(), 20);
+
+    let axe = weapons.idx(1).as_map();
+    assert_eq!(axe.idx("name").as_str(), "Great Axe");
+    assert_eq!(axe.idx("damage type").as_str(), "slash");
+    assert_eq!(axe.idx("damage").as_u64(), 30);
+
+    assert!(r
+        .idx("sounds")
+        .as_vector()
+        .iter()
+        .map(|s| s.as_str())
+        .eq(["grr", "rawr", "muahaha"].iter().cloned()));
+}
+fn read_monsters(b: &mut Bencher) {
+    let mut builder = Builder::default();
+    let mut monsters = builder.start_vector();
+    for _ in 0..100 {
+        make_monster(monsters.start_map());
+    }
+    monsters.end_vector();
+    b.bytes = builder.view().len() as u64;
+    let go = || {
+        let r = Reader::get_root(builder.view()).unwrap().as_vector();
+        assert_eq!(r.len(), 100);
+        for i in 0..100 {
+            validate_monster(r.idx(i).as_map());
+        }
+    };
+    b.iter(go);
+}
+
+benchmark_group!(
+    benches,
+    push_vec_u64_to_map,
+    push_vec_u64_to_map_reused,
+    push_vec_u64_to_map_direct,
+    push_vec_u64_to_map_direct_reused,
+    push_vec_without_indirect,
+    push_vec_with_indirect,
+    hundred_maps,
+    hundred_maps_pooled,
+    serialize_monsters,
+    read_monsters,
+);
+benchmark_main!(benches);
diff --git a/tests/rust_usage_test/bin/alloc_check.rs b/tests/rust_usage_test/bin/flatbuffers_alloc_check.rs
similarity index 68%
rename from tests/rust_usage_test/bin/alloc_check.rs
rename to tests/rust_usage_test/bin/flatbuffers_alloc_check.rs
index ae1039c..c47e86e 100644
--- a/tests/rust_usage_test/bin/alloc_check.rs
+++ b/tests/rust_usage_test/bin/flatbuffers_alloc_check.rs
@@ -29,6 +29,14 @@
 // import the flatbuffers generated code:
 extern crate flatbuffers;
 #[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
 #[path = "../../monster_test_generated.rs"]
 mod monster_test_generated;
 pub use monster_test_generated::my_game;
@@ -36,7 +44,15 @@
 // verbatim from the test suite:
 fn create_serialized_example_with_generated_code(builder: &mut flatbuffers::FlatBufferBuilder) {
     let mon = {
-        let _ = builder.create_vector_of_strings(&["these", "unused", "strings", "check", "the", "create_vector_of_strings", "function"]);
+        let _ = builder.create_vector_of_strings(&[
+            "these",
+            "unused",
+            "strings",
+            "check",
+            "the",
+            "create_vector_of_strings",
+            "function",
+        ]);
 
         let s0 = builder.create_string("test1");
         let s1 = builder.create_string("test2");
@@ -44,21 +60,36 @@
 
         // can't inline creation of this Vec3 because we refer to it by reference, so it must live
         // long enough to be used by MonsterArgs.
-        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));
+        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),
+        );
 
-        let args = my_game::example::MonsterArgs{
+        let args = my_game::example::MonsterArgs {
             hp: 80,
             mana: 150,
             name: Some(builder.create_string("MyMonster")),
             pos: Some(&pos),
             test_type: my_game::example::Any::Monster,
-            test: Some(my_game::example::Monster::create(builder, &my_game::example::MonsterArgs{
-                name: Some(fred_name),
-                ..Default::default()
-            }).as_union_value()),
+            test: Some(
+                my_game::example::Monster::create(
+                    builder,
+                    &my_game::example::MonsterArgs {
+                        name: Some(fred_name),
+                        ..Default::default()
+                    },
+                )
+                .as_union_value(),
+            ),
             inventory: Some(builder.create_vector_direct(&[0u8, 1, 2, 3, 4][..])),
-            test4: Some(builder.create_vector_direct(&[my_game::example::Test::new(10, 20),
-            my_game::example::Test::new(30, 40)])),
+            test4: Some(builder.create_vector_direct(&[
+                my_game::example::Test::new(10, 20),
+                my_game::example::Test::new(30, 40),
+            ])),
             testarrayofstring: Some(builder.create_vector(&[s0, s1])),
             ..Default::default()
         };
@@ -106,10 +137,13 @@
             assert_eq!("MyMonster", m.name());
 
             let pos = m.pos().unwrap();
-            assert_eq!(pos.x(), 1.0f32);
-            assert_eq!(pos.y(), 2.0f32);
-            assert_eq!(pos.z(), 3.0f32);
-            assert_eq!(pos.test1(), 3.0f64);
+            // We know the bits should be exactly equal here but compilers may
+            // optimize floats in subtle ways so we're playing it safe and using
+            // epsilon comparison
+            assert!((pos.x() - 1.0f32).abs() < std::f32::EPSILON);
+            assert!((pos.y() - 2.0f32).abs() < std::f32::EPSILON);
+            assert!((pos.z() - 3.0f32).abs() < std::f32::EPSILON);
+            assert!((pos.test1() - 3.0f64).abs() < std::f64::EPSILON);
             assert_eq!(pos.test2(), my_game::example::Color::Green);
             let pos_test3 = pos.test3();
             assert_eq!(pos_test3.a(), 5i16);
@@ -126,8 +160,13 @@
 
             let test4 = m.test4().unwrap();
             assert_eq!(test4.len(), 2);
-            assert_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
-                       test4[1].a() as i32 + test4[1].b() as i32, 100);
+            assert_eq!(
+                i32::from(test4[0].a())
+                    + i32::from(test4[1].a())
+                    + i32::from(test4[0].b())
+                    + i32::from(test4[1].b()),
+                100
+            );
 
             let testarrayofstring = m.testarrayofstring().unwrap();
             assert_eq!(testarrayofstring.len(), 2);
diff --git a/tests/rust_usage_test/bin/flexbuffers_alloc_check.rs b/tests/rust_usage_test/bin/flexbuffers_alloc_check.rs
new file mode 100644
index 0000000..310d1a9
--- /dev/null
+++ b/tests/rust_usage_test/bin/flexbuffers_alloc_check.rs
@@ -0,0 +1,138 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+extern crate flexbuffers;
+
+use flexbuffers::*;
+use std::alloc::{GlobalAlloc, Layout, System};
+
+/// We take over the Rust allocator to count allocations. This is super not thread safe.
+static mut NUM_ALLOCS: usize = 0;
+fn current_allocs() -> usize {
+    unsafe { NUM_ALLOCS }
+}
+struct TrackingAllocator;
+unsafe impl GlobalAlloc for TrackingAllocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        NUM_ALLOCS += 1;
+        System.alloc(layout)
+    }
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        System.dealloc(ptr, layout)
+    }
+}
+#[global_allocator]
+static T: TrackingAllocator = TrackingAllocator;
+
+/// Make some example data
+fn make_monster(mut monster: MapBuilder) {
+    monster.push("type", "great orc");
+    monster.push("age", 100u8);
+    monster.push("name", "Mr. Orc");
+    monster.push("coins", &[1, 25, 50, 100, 250]);
+    monster.push("color", &[255u8, 0, 0, 0]);
+    {
+        let mut weapons = monster.start_vector("weapons");
+        {
+            let mut hammer = weapons.start_map();
+            hammer.push("name", "hammer");
+            hammer.push("damage type", "crush");
+            hammer.push("damage", 20);
+        }
+        {
+            let mut axe = weapons.start_map();
+            axe.push("name", "Great Axe");
+            axe.push("damage type", "slash");
+            axe.push("damage", 30);
+        }
+    }
+    {
+        let mut sounds = monster.start_vector("sounds");
+        sounds.push("grr");
+        sounds.push("rawr");
+        sounds.push("muahaha");
+    }
+    // TODO(cneo): Directly pushing string slices has alloc.
+}
+
+// Read back the data from make_monster.
+fn validate_monster(flexbuffer: &[u8]) {
+    let r = Reader::get_root(flexbuffer).unwrap().as_map();
+
+    assert_eq!(r.idx("type").as_str(), "great orc");
+    assert_eq!(r.idx("age").as_u8(), 100);
+    assert_eq!(r.idx("name").as_str(), "Mr. Orc");
+
+    let coins = r.idx("coins").as_vector();
+    for (i, &c) in [1, 25, 50, 100, 250].iter().enumerate() {
+        assert_eq!(coins.idx(i).as_u16(), c);
+    }
+    let color = r.idx("color").as_vector();
+    for (i, &c) in [255, 0, 0, 0].iter().enumerate() {
+        assert_eq!(color.idx(i).as_i32(), c);
+    }
+    let weapons = r.idx("weapons").as_vector();
+    assert_eq!(weapons.len(), 2);
+
+    let hammer = weapons.idx(0).as_map();
+    assert_eq!(hammer.idx("name").as_str(), "hammer");
+    assert_eq!(hammer.idx("damage type").as_str(), "crush");
+    assert_eq!(hammer.idx("damage").as_u64(), 20);
+
+    let axe = weapons.idx(1).as_map();
+    assert_eq!(axe.idx("name").as_str(), "Great Axe");
+    assert_eq!(axe.idx("damage type").as_str(), "slash");
+    assert_eq!(axe.idx("damage").as_u64(), 30);
+
+    let sounds = r.idx("sounds").as_vector();
+    for (i, &s) in ["grr", "rawr", "muahaha"].iter().enumerate() {
+        assert_eq!(sounds.idx(i).as_str(), s);
+    }
+}
+
+// This is in a separate binary than tests because taking over the global allocator is not
+// hermetic and not thread safe.
+fn main() {
+    let start_up = current_allocs();
+
+    // Let's build a flexbuffer from a new (cold) flexbuffer builder.
+    let mut builder = Builder::default();
+    make_monster(builder.start_map());
+    let after_warmup = current_allocs();
+
+    // The builder makes some allocations while warming up.
+    assert!(after_warmup > start_up);
+    assert!(after_warmup < start_up + 20);
+
+    // A warm builder should make no allocations.
+    make_monster(builder.start_map());
+    assert_eq!(after_warmup, current_allocs());
+
+    // Nor should a reader.
+    validate_monster(builder.view());
+    assert_eq!(after_warmup, current_allocs());
+
+    // Do it again just for kicks.
+    make_monster(builder.start_map());
+    validate_monster(builder.view());
+    assert_eq!(after_warmup, current_allocs());
+
+    let final_allocs = current_allocs(); // dbg! does allocate.
+    dbg!(start_up, after_warmup, final_allocs);
+}
+
+#[test]
+fn no_extra_allocations() {
+    main()
+}
diff --git a/tests/rust_usage_test/bin/monster_example.rs b/tests/rust_usage_test/bin/monster_example.rs
index 3c9a0a0..d0b75d7 100644
--- a/tests/rust_usage_test/bin/monster_example.rs
+++ b/tests/rust_usage_test/bin/monster_example.rs
@@ -1,6 +1,14 @@
 extern crate flatbuffers;
 
 #[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
 #[path = "../../monster_test_generated.rs"]
 mod monster_test_generated;
 pub use monster_test_generated::my_game;
@@ -13,7 +21,7 @@
     f.read_to_end(&mut buf).expect("file reading failed");
 
     let monster = my_game::example::get_root_as_monster(&buf[..]);
-    println!("{}", monster.hp());     // `80`
-    println!("{}", monster.mana());   // default value of `150`
+    println!("{}", monster.hp()); // `80`
+    println!("{}", monster.mana()); // default value of `150`
     println!("{:?}", monster.name()); // Some("MyMonster")
 }
diff --git a/tests/rust_usage_test/tests/flexbuffers_tests/binary_format.rs b/tests/rust_usage_test/tests/flexbuffers_tests/binary_format.rs
new file mode 100644
index 0000000..ce69511
--- /dev/null
+++ b/tests/rust_usage_test/tests/flexbuffers_tests/binary_format.rs
@@ -0,0 +1,536 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use flexbuffers::*;
+use serde::Serialize;
+
+#[test]
+fn store_13() {
+    let buf = singleton(13i32);
+    assert_eq!(&buf, &[13, 4, 1]);
+}
+#[test]
+fn store_2pow20() {
+    let buf = singleton(1_048_576i32);
+    assert_eq!(
+        &buf,
+        &[
+            0,
+            0,
+            16,
+            0,          // 2^20 in LE bytes.
+            1 << 2 | 2, // Int 32bit
+            4           // Root width 32 bit
+        ]
+    );
+}
+
+#[test]
+fn heterogenous_vector_of_string_because_width() {
+    // Each string is 32 characters. They are 256 bytes altogether.
+    // This forces the vector to be W16 because of the large offsets.
+    let test_data = [
+        "0aaabbbbccccddddeeeeffffgggghhh",
+        "1aaabbbbccccddddeeeeffffgggghhh",
+        "2aaabbbbccccddddeeeeffffgggghhh",
+        "3aaabbbbccccddddeeeeffffgggghhh",
+        "4aaabbbbccccddddeeeeffffgggghhh",
+        "5aaabbbbccccddddeeeeffffgggghhh",
+        "6aaabbbbccccddddeeeeffffgggghhh",
+        "7aaabbbbccccddddeeeeffffgggghhh",
+    ];
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    for &s in test_data.iter() {
+        v.push(s);
+    }
+    v.end_vector();
+    let mut expected = vec![];
+    for &s in test_data.iter() {
+        expected.push(s.len() as u8);
+        expected.extend(s.bytes());
+        expected.push(b'\0');
+    }
+    expected.extend(8u16.to_le_bytes().iter()); // Length.
+    for i in 0..test_data.len() as u16 {
+        let offset = 32 * (8 - i) + 9 + i;
+        expected.extend(offset.to_le_bytes().iter());
+    }
+    for _ in 0..test_data.len() {
+        expected.push(5 << 2 | 0); // String, W8.
+    }
+    expected.push(24); // Offset to Vector.
+    expected.push(10 << 2 | 1); // Vector, W16.
+    expected.push(1); // Root width W8.
+    assert_eq!(fxb.view(), expected.as_slice());
+}
+
+#[test]
+fn store_vec_uint_16() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(256u16);
+    v.push(257u16);
+    v.push(258u16);
+    v.push(259u16);
+    v.push(0u8); // This still becomes u16.
+    v.end_vector();
+    assert_eq!(
+        fxb.view(),
+        &[
+            5,
+            0,
+            0,
+            1,
+            1,
+            1,
+            2,
+            1,
+            3,
+            1,
+            0,
+            0,           // Data
+            10,          // Vector offset.
+            12 << 2 | 1, // (VectorUInt, W16 - referring to data).
+            1,           // Root width W8 - referring to vector.
+        ]
+    );
+}
+
+quickcheck! {
+    fn qc_f32(x: f32) -> bool {
+        let fxb = singleton(x);
+        let mut expected = x.to_le_bytes().to_vec();
+        expected.push(3 << 2 | 2);  // Float W32.
+        expected.push(4); // Root width W32.
+        println!("{:?}: {:?} vs {:?} cmp {:?}", x, &fxb, &expected, fxb==expected);
+        fxb == expected
+    }
+}
+
+#[test]
+fn singleton_vector_uint_4_16bit() {
+    let buf = singleton(&[4u16, 16, 64, 256]);
+    assert_eq!(
+        &buf,
+        &[
+            4,
+            0,
+            16,
+            0,
+            64,
+            0,
+            0,
+            1,           // Data
+            8,           // Vector offset.
+            23 << 2 | 1, // (VectorUInt, W16 - referring to data).
+            1,           // Root width W8 - referring to vector.
+        ]
+    );
+}
+#[test]
+fn store_u64() {
+    let buf = singleton(u64::max_value() - 10);
+    assert_eq!(
+        &buf,
+        &[
+            245,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,        // max value - 10.
+            2 << 2 | 3, // (UInt, W64)
+            8,          // Root width W64.
+        ]
+    );
+}
+#[test]
+fn vector_uint4() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(2u8);
+    v.push(3u8);
+    v.push(5u8);
+    v.push(7u8);
+    v.end_vector();
+    assert_eq!(
+        &fxb.view(),
+        &[
+            2,
+            3,
+            5,
+            7,           // data
+            4,           // Root (offset)
+            23 << 2 | 0, // Root type VectorUInt4, BitWidth::W8
+            1,           // Root bitwidth W8
+        ]
+    );
+}
+#[test]
+fn nested_vector() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(0u8);
+    {
+        let mut nested = v.start_vector();
+        nested.push(1u8);
+        nested.push(2u8);
+        nested.push(3u8);
+    }
+    v.push(-42i8);
+    v.end_vector();
+    assert_eq!(
+        fxb.view(),
+        &[
+            1,
+            2,
+            3, // Nested vector
+            3,
+            0,
+            5,
+            214,         // Root Vector: size, v[0], v[1] (offset), v[2] as u8
+            2 << 2 | 0,  // v[0]: (UInt, W8)
+            20 << 2 | 0, // v[1]: (VectorUInt3, W8)
+            1 << 2 | 0,  // v[2]: (Int, W8)
+            6,           // Root points to Root vector
+            10 << 2 | 0, // Root type and width (Vector, W8)
+            1,           // Root bytes
+        ]
+    )
+}
+
+#[test]
+fn nested_vector_push_direct() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(0u8);
+    v.push(&[1u8, 2, 3]);
+    v.push(-42i8);
+    v.end_vector();
+    assert_eq!(
+        fxb.view(),
+        &[
+            1,
+            2,
+            3, // Nested VectorUInt3
+            3,
+            0,
+            5,
+            214,         // Root Vector: size, v[0], v[1] (offset), v[2] as u8
+            2 << 2 | 0,  // v[0]: (UInt, W8)
+            20 << 2 | 0, // v[1]: (VectorUInt3, W8)
+            1 << 2 | 0,  // v[2]: (Int, W8)
+            6,           // Root points to Root vector
+            10 << 2 | 0, // Root type and width (Vector, W8)
+            1,           // Root bytes
+        ]
+    )
+}
+#[test]
+fn store_map_index_into_it() {
+    let mut fxb = Builder::default();
+    {
+        let mut m = fxb.start_map();
+        m.push("foo", 17u8);
+        m.push("bar", 33u16);
+        m.push("baz", 41u32);
+    }
+    assert_eq!(
+        fxb.view(),
+        &[
+            b'f',
+            b'o',
+            b'o',
+            b'\0',
+            b'b',
+            b'a',
+            b'r',
+            b'\0',
+            b'b',
+            b'a',
+            b'z',
+            b'\0',
+            3,
+            9,
+            6,
+            15, // Keys vector (note "bar" < "baz" < "foo").
+            3,
+            1,
+            3, // map prefix
+            33,
+            41,
+            17, // values
+            8,
+            8,
+            8,          // types (UInt, W8) ~ (2 << 2 | 0)
+            6,          // Offset to map (root)
+            9 << 2 | 0, // Root type (map)
+            1,          // Root bytes
+        ]
+    );
+}
+#[test]
+fn utf8_snowman() {
+    let buf = singleton("snowman ☃︎");
+    assert_eq!(
+        &buf,
+        &[
+            14, // Byte length (besides extra null terminator).
+            b's',
+            b'n',
+            b'o',
+            b'w',
+            b'm',
+            b'a',
+            b'n',
+            b' ',
+            226,
+            152,
+            131, // snowman bytes
+            239,
+            184,
+            142,    // UTF Variation selector 15
+            0,      // extra null terminator.
+            15,     // Offset to string start.
+            5 << 2, // String, W8
+            1,      // Root bytes
+        ]
+    );
+    let r = Reader::get_root(&buf).unwrap();
+    assert_eq!(r.get_str(), Ok("snowman ☃︎"));
+}
+#[test]
+fn indirect_numbers() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(IndirectUInt(u64::max_value()));
+    v.push(IndirectInt(i64::min_value()));
+    // TODO(cneo): Something about Float EPSILON and casting leads to a different binary format.
+    v.push(IndirectFloat(std::f64::consts::PI));
+    v.push(0u32); // This is stored in 8 bits instead of 64 because of indirection.
+    v.end_vector();
+    assert_eq!(
+        fxb.view(),
+        vec![
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255,
+            255, // u64 max
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            0,
+            128, // i64 min value
+            24,
+            45,
+            68,
+            84,
+            251,
+            33,
+            9,
+            64, // f64 PI.
+            4,  // Vector length
+            25,
+            18,
+            11,
+            0,           // offsets to the indirect numbers and zero.
+            7 << 2 | 3,  // IndirectUInt 64 bit
+            6 << 2 | 3,  // IndirectInt 64 bit
+            8 << 2 | 3,  // IndirectFloat 64 bit
+            2 << 2 | 0,  // (inline) UInt 8 bit
+            8,           // Offset to Root.
+            10 << 2 | 0, // Vector 8 bit
+            1,           // 1 byte root
+        ]
+        .as_slice()
+    )
+}
+#[test]
+fn indirect_2p5x_smaller() {
+    let mut builder = Builder::default();
+    let mut v = builder.start_vector();
+    for i in 0..512 {
+        v.push(i);
+    }
+    v.push(i64::max_value());
+    v.end_vector();
+    let len_without_indirect = builder.view().len() as f32;
+
+    let mut v = builder.start_vector();
+    for i in 0..512 {
+        v.push(i);
+    }
+    v.push(IndirectInt(i64::max_value()));
+    v.end_vector();
+    let len_with_indirect = builder.view().len() as f32;
+    dbg!(len_with_indirect, len_without_indirect);
+    assert!(len_with_indirect * 2.5 < len_without_indirect);
+}
+#[test]
+fn key_pool() {
+    let mut builder = Builder::default();
+    let mut vector = builder.start_vector();
+    for _ in 0..2 {
+        let mut m = vector.start_map();
+        m.push("a", 42u8);
+        m.push("b", 42u8);
+        m.push("c", 42u8);
+    }
+    vector.end_vector();
+
+    assert_eq!(
+        builder.view(),
+        vec![
+            b'a',
+            b'\0',
+            b'b',
+            b'\0',
+            b'c',
+            b'\0',
+            3,
+            7,
+            6,
+            5, // Key vector 0
+            3,
+            1,
+            3,
+            42,
+            42,
+            42,
+            2 << 2,
+            2 << 2,
+            2 << 2, // Map 0.
+            3,
+            20,
+            19,
+            18, // Key vector 1 (shares keys with key vector 0).
+            3,
+            1,
+            3,
+            42,
+            42,
+            42,
+            2 << 2,
+            2 << 2,
+            2 << 2, // Map 1.
+            2,
+            20,
+            8,
+            9 << 2,
+            9 << 2, // Vector containing the maps.
+            4,
+            10 << 2,
+            1, // Root.
+        ]
+        .as_slice()
+    );
+}
+
+#[test]
+fn serialize_unit() {
+    #[derive(Serialize)]
+    struct Foo;
+    let mut s = FlexbufferSerializer::new();
+    Foo.serialize(&mut s).unwrap();
+    assert_eq!(s.view(), &[0, 0, 1]);
+}
+
+#[test]
+fn serialize_i8() {
+    let mut s = FlexbufferSerializer::new();
+    13i8.serialize(&mut s).unwrap();
+    assert_eq!(s.view(), &[13, 4, 1]);
+}
+#[test]
+fn serialize_tuple_struct_i8() {
+    #[derive(Serialize)]
+    struct Foo(i32);
+    let mut s = FlexbufferSerializer::new();
+    Foo(13).serialize(&mut s).unwrap();
+    assert_eq!(s.view(), &[13, 4, 1]);
+}
+#[test]
+fn serialize_tuple_tuple_struct_i8_is_inlined() {
+    #[derive(Serialize)]
+    struct Foo(i32);
+    #[derive(Serialize)]
+    struct Bar(Foo);
+    let mut s = FlexbufferSerializer::new();
+    Bar(Foo(13)).serialize(&mut s).unwrap();
+    assert_eq!(s.view(), &[13, 4, 1]);
+}
+#[test]
+fn align_8byte() {
+    let mut b = Builder::default();
+    let mut v = b.start_vector();
+    v.push(IndirectUInt(42));
+    v.push(&[u64::max_value(); 2]);
+    v.end_vector();
+    assert_eq!(
+        b.view()[..16],
+        [
+            42, 0, 0, 0, 0, 0, 0, 0, // padding
+            255, 255, 255, 255, 255, 255, 255, 255, // the first u64 max value.
+        ]
+    );
+}
+#[test]
+fn align_4byte() {
+    let mut b = Builder::default();
+    let mut v = b.start_vector();
+    v.push(IndirectUInt(42));
+    v.push(&[u32::max_value(); 2]);
+    v.end_vector();
+    assert_eq!(
+        b.view()[..8],
+        [
+            42, 0, 0, 0, // padding
+            255, 255, 255, 255, // the first u32 max value.
+        ]
+    );
+}
+#[test]
+fn align_2byte() {
+    let mut b = Builder::default();
+    let mut v = b.start_vector();
+    v.push(IndirectUInt(42));
+    v.push(&[u16::max_value(); 2]);
+    v.end_vector();
+    assert_eq!(
+        b.view()[..4],
+        [
+            42, 0, // padding
+            255, 255, // the first u16 max value.
+        ]
+    );
+}
+#[test]
+fn align_1byte() {
+    let mut b = Builder::default();
+    let mut v = b.start_vector();
+    v.push(IndirectUInt(42));
+    v.push(&[u8::max_value(); 2]);
+    v.end_vector();
+    assert_eq!(b.view()[..2], [42, 255]); // No padding.
+}
diff --git a/tests/rust_usage_test/tests/flexbuffers_tests/interop.rs b/tests/rust_usage_test/tests/flexbuffers_tests/interop.rs
new file mode 100644
index 0000000..54ae1fd
--- /dev/null
+++ b/tests/rust_usage_test/tests/flexbuffers_tests/interop.rs
@@ -0,0 +1,50 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use flexbuffers::*;
+
+#[test]
+fn read_golden_flexbuffer() {
+    let s =
+        std::fs::read("../gold_flexbuffer_example.bin").expect("Unable to read golden flexbuffer.");
+    let r = Reader::get_root(&s).unwrap();
+    let m = r.as_map();
+
+    let vec = m.idx("vec").as_vector();
+    assert_eq!(vec.idx(0).as_i8(), -100);
+    assert_eq!(vec.idx(1).as_str(), "Fred");
+    assert_eq!(vec.idx(2).as_f32(), 4.0);
+    assert_eq!(vec.idx(3).as_blob(), Blob(&[77]));
+    assert_eq!(vec.idx(4).flexbuffer_type(), FlexBufferType::Bool);
+    assert_eq!(vec.idx(4).as_bool(), false);
+    assert_eq!(vec.idx(5).as_f64(), 4.0);
+
+    let bar = m.idx("bar").as_vector();
+    for (i, &x) in [1, 2, 3].iter().enumerate() {
+        assert_eq!(bar.idx(i).as_i8(), x);
+    }
+    let bar3 = m.idx("bar3").as_vector();
+    for (i, &x) in [1, 2, 3].iter().enumerate() {
+        assert_eq!(bar3.idx(i).as_i8(), x);
+    }
+    let bools = m.idx("bools").as_vector();
+    for (i, &b) in [true, false, true, false].iter().enumerate() {
+        assert_eq!(bools.idx(i).as_bool(), b)
+    }
+
+    assert_eq!(m.idx("bool").as_bool(), true);
+    assert_eq!(m.idx("foo").as_f64(), 100.0);
+    let mymap = m.idx("mymap").as_map();
+    assert_eq!(mymap.idx("foo").as_str(), "Fred");
+}
diff --git a/tests/rust_usage_test/tests/flexbuffers_tests/mod.rs b/tests/rust_usage_test/tests/flexbuffers_tests/mod.rs
new file mode 100644
index 0000000..2fccdb3
--- /dev/null
+++ b/tests/rust_usage_test/tests/flexbuffers_tests/mod.rs
@@ -0,0 +1,19 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+mod binary_format;
+mod interop;
+mod other_api;
+mod qc_serious;
+mod rwyw;
diff --git a/tests/rust_usage_test/tests/flexbuffers_tests/other_api.rs b/tests/rust_usage_test/tests/flexbuffers_tests/other_api.rs
new file mode 100644
index 0000000..430cae5
--- /dev/null
+++ b/tests/rust_usage_test/tests/flexbuffers_tests/other_api.rs
@@ -0,0 +1,190 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use flexbuffers::*;
+use quickcheck::QuickCheck;
+
+#[test]
+fn qc_reader_no_crash() {
+    fn no_crash(xs: Vec<u8>) -> bool {
+        let r = Reader::get_root(&xs);
+        r.is_err() || r.is_ok()
+    }
+    QuickCheck::new()
+        .min_tests_passed(10_000_000)
+        .quicktest(no_crash as fn(Vec<u8>) -> bool)
+        .unwrap();
+
+    no_crash(vec![0, 10 << 2 | 2, 0]);
+}
+#[test]
+fn as_num() {
+    let mut fxb = Builder::default();
+    let mut m = fxb.start_map();
+    m.push("a", &[-1i8, -2, -3, -4]);
+    m.push("b", 250i64);
+    m.push("c", 5000u16);
+    m.end_map();
+
+    let r = Reader::get_root(fxb.view()).unwrap();
+    assert_eq!(r.as_i8(), 3); // length.
+    assert_eq!(r.as_i16(), 3);
+    assert_eq!(r.as_i32(), 3);
+    assert_eq!(r.as_i64(), 3);
+    assert_eq!(r.as_u8(), 3);
+    assert_eq!(r.as_u16(), 3);
+    assert_eq!(r.as_u32(), 3);
+    assert_eq!(r.as_u64(), 3);
+    assert_eq!(r.as_f32(), 3.0);
+    assert_eq!(r.as_f64(), 3.0);
+
+    let m = r.as_map();
+    let a = m.index("a").unwrap();
+    assert_eq!(a.as_f32(), 4.0); // length.
+    assert_eq!(a.as_f64(), 4.0); // length.
+    assert_eq!(a.as_vector().idx(0).as_i8(), -1);
+    assert_eq!(a.as_vector().idx(1).as_i16(), -2);
+    assert_eq!(a.as_vector().idx(2).as_i32(), -3);
+    assert_eq!(a.as_vector().idx(3).as_i64(), -4);
+
+    let b = m.index("b").unwrap();
+    assert_eq!(b.as_u8(), 250);
+    assert_eq!(b.as_u16(), 250);
+    assert_eq!(b.as_u32(), 250);
+    assert_eq!(b.as_u64(), 250);
+    assert_eq!(b.as_i8(), 0); // overflow
+    assert_eq!(b.as_i16(), 250);
+    assert_eq!(b.as_i32(), 250);
+    assert_eq!(b.as_i64(), 250);
+
+    let c = m.index("c").unwrap();
+    assert_eq!(c.as_i64(), 5000);
+    assert_eq!(c.as_u64(), 5000);
+    assert_eq!(c.as_f32(), 5000.0);
+    assert_eq!(c.as_u8(), 0); // overflow
+    assert_eq!(c.as_u16(), 5000);
+    assert_eq!(c.as_u32(), 5000);
+    assert_eq!(c.as_u64(), 5000);
+    assert_eq!(c.as_i8(), 0); // overflow
+    assert_eq!(c.as_i16(), 5000);
+    assert_eq!(c.as_i32(), 5000);
+    assert_eq!(c.as_i64(), 5000);
+}
+#[test]
+fn string_as_num() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push("3.1415");
+    v.push("9.001e3");
+    v.push("42");
+    v.end_vector();
+    let r = Reader::get_root(fxb.view()).unwrap();
+
+    let v0 = r.as_vector().idx(0);
+    assert_eq!(v0.as_f64(), 3.1415);
+    assert_eq!(v0.as_f32(), 3.1415);
+    assert_eq!(v0.as_u8(), 0);
+    assert_eq!(v0.as_u16(), 0);
+    assert_eq!(v0.as_u32(), 0);
+    assert_eq!(v0.as_u64(), 0);
+    assert_eq!(v0.as_i8(), 0);
+    assert_eq!(v0.as_i16(), 0);
+    assert_eq!(v0.as_i32(), 0);
+    assert_eq!(v0.as_i64(), 0);
+
+    let v1 = r.as_vector().idx(1);
+    assert_eq!(v1.as_f64(), 9001.0);
+    assert_eq!(v1.as_f32(), 9001.0);
+    assert_eq!(v1.as_u8(), 0);
+    assert_eq!(v1.as_u16(), 0);
+    assert_eq!(v1.as_u32(), 0);
+    assert_eq!(v1.as_u64(), 0);
+    assert_eq!(v1.as_i8(), 0);
+    assert_eq!(v1.as_i16(), 0);
+    assert_eq!(v1.as_i32(), 0);
+    assert_eq!(v1.as_i64(), 0);
+    assert_eq!(v1.as_i32(), 0);
+
+    let v2 = r.as_vector().idx(2);
+    assert_eq!(v2.as_f64(), 42.0);
+    assert_eq!(v2.as_f32(), 42.0);
+    assert_eq!(v2.as_u8(), 42);
+    assert_eq!(v2.as_u16(), 42);
+    assert_eq!(v2.as_u32(), 42);
+    assert_eq!(v2.as_u64(), 42);
+    assert_eq!(v2.as_i8(), 42);
+    assert_eq!(v2.as_i16(), 42);
+    assert_eq!(v2.as_i32(), 42);
+    assert_eq!(v2.as_i64(), 42);
+    assert_eq!(v2.as_i32(), 42);
+}
+#[test]
+fn null_reader() {
+    let n = Reader::default();
+    assert_eq!(n.as_i8(), 0);
+    assert_eq!(n.as_i16(), 0);
+    assert_eq!(n.as_i32(), 0);
+    assert_eq!(n.as_i64(), 0);
+    assert_eq!(n.as_u8(), 0);
+    assert_eq!(n.as_u16(), 0);
+    assert_eq!(n.as_u32(), 0);
+    assert_eq!(n.as_u64(), 0);
+    assert_eq!(n.as_f32(), 0.0);
+    assert_eq!(n.as_f64(), 0.0);
+    assert!(n.get_i64().is_err());
+    assert!(n.get_u64().is_err());
+    assert!(n.get_f64().is_err());
+    assert!(n.as_vector().is_empty());
+    assert!(n.as_map().is_empty());
+    assert_eq!(n.as_vector().idx(1).flexbuffer_type(), FlexBufferType::Null);
+    assert_eq!(n.as_map().idx("1").flexbuffer_type(), FlexBufferType::Null);
+}
+#[test]
+fn get_root_deref_oob() {
+    let s = &[
+        4, // Deref out of bounds
+        (FlexBufferType::Vector as u8) << 2 | BitWidth::W8 as u8,
+        1,
+    ];
+    assert!(Reader::get_root(s).is_err());
+}
+#[test]
+fn get_root_deref_u64() {
+    let s = &[
+        0,
+        0,
+        (FlexBufferType::IndirectUInt as u8) << 2 | BitWidth::W64 as u8,
+        1,
+    ];
+    // The risk of crashing is reading 8 bytes from index 0.
+    assert_eq!(Reader::get_root(s).unwrap().as_u64(), 0);
+}
+
+#[test]
+#[should_panic]
+fn build_map_panic_on_repeated_key() {
+    let mut b = Builder::default();
+    let mut m = b.start_map();
+    m.push("foo", 5u8);
+    m.push("foo", 6u8);
+    m.end_map();
+}
+#[test]
+#[should_panic]
+fn build_map_panic_on_internal_null() {
+    let mut b = Builder::default();
+    let mut m = b.start_map();
+    m.push("foo\0", 5u8);
+    m.end_map();
+}
diff --git a/tests/rust_usage_test/tests/flexbuffers_tests/qc_serious.rs b/tests/rust_usage_test/tests/flexbuffers_tests/qc_serious.rs
new file mode 100644
index 0000000..abd1ced
--- /dev/null
+++ b/tests/rust_usage_test/tests/flexbuffers_tests/qc_serious.rs
@@ -0,0 +1,145 @@
+use super::rwyw::NonNullString;
+use flexbuffers::*;
+use quickcheck::{Arbitrary, Gen};
+use serde::{Deserialize, Serialize};
+use std::collections::BTreeMap;
+
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
+enum Enum {
+    Unit,
+    U8(u8),
+    U16(u16),
+    U32(u32),
+    U64(u64),
+    Us(u8, u16, u32, u64),
+    I8(i8),
+    I16(i16),
+    I32(i32),
+    I64(i64),
+    Is(i8, i16, i32, i64),
+    F32(f32),
+    F64(f64),
+    Fs(f32, f64),
+    String(String),
+    Strings(String, String),
+    Everything(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64, String),
+    Arrays {
+        a: Array3<u16>,
+        b: Array4<i32>,
+        c: Array2<f64>,
+    },
+    Blobs(#[serde(with = "serde_bytes")] Vec<u8>),
+}
+
+// There is some upstream bug in deriving Arbitrary for Enum so we manually implement it here.
+impl Arbitrary for Enum {
+    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+        match g.gen_range(0, 18) {
+            0 => Enum::Unit,
+            1 => Enum::U8(<u8>::arbitrary(g)),
+            2 => Enum::U16(<u16>::arbitrary(g)),
+            3 => Enum::U32(<u32>::arbitrary(g)),
+            4 => Enum::U64(<u64>::arbitrary(g)),
+            5 => {
+                let (a, b, c, d) = <(u8, u16, u32, u64)>::arbitrary(g);
+                Enum::Us(a, b, c, d)
+            }
+            6 => Enum::I8(<i8>::arbitrary(g)),
+            7 => Enum::I16(<i16>::arbitrary(g)),
+            8 => Enum::I32(<i32>::arbitrary(g)),
+            9 => Enum::I64(<i64>::arbitrary(g)),
+            10 => {
+                let (a, b, c, d) = <(i8, i16, i32, i64)>::arbitrary(g);
+                Enum::Is(a, b, c, d)
+            }
+            11 => Enum::F32(<f32>::arbitrary(g)),
+            12 => Enum::F64(<f64>::arbitrary(g)),
+            13 => {
+                let (a, b) = <(f32, f64)>::arbitrary(g);
+                Enum::Fs(a, b)
+            }
+            14 => Enum::String(String::arbitrary(g)),
+            15 => {
+                let (a, b) = <(String, String)>::arbitrary(g);
+                Enum::Strings(a, b)
+            }
+            16 => Enum::Everything(
+                <u8>::arbitrary(g),
+                <u16>::arbitrary(g),
+                <u32>::arbitrary(g),
+                <u64>::arbitrary(g),
+                <i8>::arbitrary(g),
+                <i16>::arbitrary(g),
+                <i32>::arbitrary(g),
+                <i64>::arbitrary(g),
+                <f32>::arbitrary(g),
+                <f64>::arbitrary(g),
+                <String>::arbitrary(g),
+            ),
+            17 => {
+                let a = Array3::arbitrary(g);
+                let b = Array4::arbitrary(g);
+                let c = Array2::arbitrary(g);
+                Enum::Arrays { a, b, c }
+            }
+            _ => unreachable!(),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Arbitrary, PartialEq, Serialize, Deserialize)]
+struct Unit;
+
+#[derive(Debug, Clone, Arbitrary, PartialEq, Serialize, Deserialize)]
+struct NewType(bool);
+
+#[derive(Debug, Clone, Arbitrary, PartialEq, Serialize, Deserialize)]
+struct Tuple(bool, u8, i16, f32, String);
+
+#[derive(Debug, Clone, Arbitrary, PartialEq, Serialize, Deserialize)]
+struct Struct {
+    a: Vec<Enum>,
+    b: BTreeMap<NonNullString, Enum>,
+    c: Tuple,
+    d: (Unit, Unit),
+    e: Array4<NewType>,
+}
+
+#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
+struct Array2<A: Arbitrary>([A; 2]);
+#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
+struct Array3<A: Arbitrary>([A; 3]);
+#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Serialize, Deserialize)]
+struct Array4<A: Arbitrary>([A; 4]);
+
+impl<A: Arbitrary> Arbitrary for Array2<A> {
+    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+        Array2([A::arbitrary(g), A::arbitrary(g)])
+    }
+}
+impl<A: Arbitrary> Arbitrary for Array3<A> {
+    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+        Array3([A::arbitrary(g), A::arbitrary(g), A::arbitrary(g)])
+    }
+}
+impl<A: Arbitrary> Arbitrary for Array4<A> {
+    fn arbitrary<G: Gen>(g: &mut G) -> Self {
+        Array4([
+            A::arbitrary(g),
+            A::arbitrary(g),
+            A::arbitrary(g),
+            A::arbitrary(g),
+        ])
+    }
+}
+
+quickcheck! {
+    fn qc_serious(x: Struct) -> bool {
+        let mut s = FlexbufferSerializer::new();
+        x.serialize(&mut s).unwrap();
+        let r = Reader::get_root(s.view()).unwrap();
+        println!("{}", r);
+        let x2 = Struct::deserialize(r).unwrap();
+        x == x2
+    }
+}
diff --git a/tests/rust_usage_test/tests/flexbuffers_tests/rwyw.rs b/tests/rust_usage_test/tests/flexbuffers_tests/rwyw.rs
new file mode 100644
index 0000000..7ae7974
--- /dev/null
+++ b/tests/rust_usage_test/tests/flexbuffers_tests/rwyw.rs
@@ -0,0 +1,508 @@
+// Copyright 2019 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Read what you wrote.
+use flexbuffers::*;
+use quickcheck;
+use serde::{Deserialize, Serialize};
+
+// TODO(cneo): Upstream this to the quickcheck crate. Also, write a macro to derive Arbitrary.
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
+pub struct NonNullString(String);
+impl quickcheck::Arbitrary for NonNullString {
+    fn arbitrary<G: quickcheck::Gen>(g: &mut G) -> Self {
+        let size = std::cmp::min(1, usize::arbitrary(g));
+        NonNullString(
+            (0..)
+                .map(|_| <char>::arbitrary(g))
+                .filter(|&b| b != '\0')
+                .take(size)
+                .collect(),
+        )
+    }
+}
+
+quickcheck! {
+    fn qc_vec_bool(xs: Vec<bool>) -> bool {
+        let mut builder = Builder::default();
+        let mut v = builder.start_vector();
+        for &x in &xs {
+            v.push(x);
+        }
+        v.end_vector();
+        let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+        xs.iter().enumerate().all(|(i, &x)| r.index(i).unwrap().get_bool().unwrap() == x)
+    }
+    fn qc_vec_uint(xs: Vec<u64>) -> bool {
+        let mut builder = Builder::default();
+        let mut v = builder.start_vector();
+        for &x in &xs {
+            v.push(x);
+        }
+        v.end_vector();
+        let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+        xs.iter().enumerate().all(|(i, &x)| r.idx(i).as_u64() == x)
+    }
+    fn qc_vec_int(xs: Vec<i64>) -> bool {
+        let mut builder = Builder::default();
+        let mut v = builder.start_vector();
+        for &x in &xs {
+            v.push(x);
+        }
+        v.end_vector();
+        let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+        xs.iter().enumerate().all(|(i, &x)| r.idx(i).as_i64() == x)
+    }
+    fn qc_vec_float(xs: Vec<f64>) -> bool {
+        let mut builder = Builder::default();
+        let mut v = builder.start_vector();
+        for &x in &xs {
+            v.push(x);
+        }
+        v.end_vector();
+        let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+        xs.iter().enumerate().all(|(i, &x)| (r.idx(i).as_f64() - x).abs() < std::f64::EPSILON)
+    }
+    fn qc_vec_string(xs: Vec<String>) -> bool {
+        let mut builder = Builder::default();
+        let mut v = builder.start_vector();
+        for x in &xs {
+            v.push(x as &str);
+        }
+        v.end_vector();
+        let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+        xs.iter().enumerate().all(|(i, x)| (r.idx(i).as_str() == x))
+    }
+    fn qc_map_int(xs: std::collections::BTreeMap<NonNullString, i64>) -> bool {
+        let mut builder = Builder::default();
+        let mut m = builder.start_map();
+        for (k, &v) in &xs {
+            m.push(&k.0, v);
+        }
+        m.end_map();
+        let r = Reader::get_root(&builder.view()).unwrap().as_map();
+        xs.iter().enumerate().all(|(i, (k, &v))| {
+            r.idx(i).as_i64() == v && r.idx(k.0.as_str()).as_i64() == v
+        })
+    }
+    fn qc_map_string(xs: std::collections::BTreeMap<NonNullString, String>) -> bool {
+        let mut builder = Builder::default();
+        let mut m = builder.start_map();
+        for (k, v) in &xs {
+            m.push(&k.0, v as &str);
+        }
+        m.end_map();
+        let r = Reader::get_root(&builder.view()).unwrap().as_map();
+        xs.iter().enumerate().all(|(i, (k, v))| {
+            r.idx(i).as_str() == v && r.idx(k.0.as_str()).as_str() == v
+        })
+    }
+    fn qc_blob(xs: Vec<Vec<u8>>) -> bool {
+        let mut builder = Builder::default();
+        let mut v = builder.start_vector();
+        for x in &xs {
+            v.push(Blob(&x));
+        }
+        v.end_vector();
+        let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+        xs.iter().enumerate().all(
+            |(i, x)| r.idx(i).get_blob().unwrap().0.iter().eq(x.iter())
+        )
+    }
+    fn qc_serde_ints(
+        u8s: Vec<u8>,
+        u16s: Vec<u16>,
+        u32s: Vec<u32>,
+        u64s: Vec<u64>,
+        i8s: Vec<i8>,
+        i16s: Vec<i16>,
+        i32s: Vec<i32>,
+        i64s: Vec<i64>
+    ) -> bool {
+        #[derive(Serialize, Deserialize, PartialEq)]
+        struct Foo {
+            u8s: Vec<u8>,
+            u16s: Vec<u16>,
+            u32s: Vec<u32>,
+            u64s: Vec<u64>,
+            i8s: Vec<i8>,
+            i16s: Vec<i16>,
+            i32s: Vec<i32>,
+            i64s: Vec<i64>,
+        }
+        let mut ser = FlexbufferSerializer::new();
+        let foo1 = Foo { u8s, u16s, u32s, u64s, i8s, i16s, i32s, i64s };
+        foo1.serialize(&mut ser).unwrap();
+        let r = Reader::get_root(ser.view()).unwrap();
+        let foo2 = Foo::deserialize(r).unwrap();
+        foo1 == foo2
+    }
+    fn qc_serde_others(
+        bools: Vec<bool>,
+        strings: Vec<String>,
+        f32s: Vec<f32>,
+        f64s: Vec<f64>
+    ) -> bool {
+        #[derive(Serialize, Deserialize, PartialEq)]
+        struct Foo {
+            bools: Vec<bool>,
+            strings: Vec<String>,
+            f32s: Vec<f32>,
+            f64s: Vec<f64>,
+        }
+        let mut ser = FlexbufferSerializer::new();
+        let foo1 = Foo { bools, strings, f32s, f64s };
+        foo1.serialize(&mut ser).unwrap();
+        let r = Reader::get_root(ser.view()).unwrap();
+        let foo2 = Foo::deserialize(r).unwrap();
+        foo1 == foo2
+    }
+    fn qc_serde_others2(
+        bools: Vec<bool>,
+        strings: Vec<String>,
+        f32s: Vec<f32>,
+        f64s: Vec<f64>
+    ) -> bool {
+        #[derive(Serialize, Deserialize, PartialEq)]
+        struct Foo (Vec<bool>, Vec<String>, Vec<f32>, Vec<f64>);
+        let mut ser = FlexbufferSerializer::new();
+        let foo1 = Foo(bools, strings, f32s, f64s);
+        foo1.serialize(&mut ser).unwrap();
+        let r = Reader::get_root(ser.view()).unwrap();
+        let foo2 = Foo::deserialize(r).unwrap();
+        foo1 == foo2
+    }
+
+}
+
+#[test]
+fn empty_vectors() {
+    #[derive(PartialEq, Serialize, Deserialize, Default, Debug)]
+    struct Foo(Vec<u8>, Vec<i8>);
+    let foo1 = Foo::default();
+    let mut s = FlexbufferSerializer::new();
+    foo1.serialize(&mut s).unwrap();
+    dbg!(s.view());
+    let r = Reader::get_root(s.view()).unwrap();
+    let foo2 = Foo::deserialize(r).unwrap();
+    assert_eq!(foo1, foo2);
+}
+
+#[test]
+fn string() {
+    let mut builder = Builder::default();
+    let mut v = builder.start_vector();
+    v.push("foo");
+    v.push("barrr");
+    v.push("bazzzzzz");
+    v.end_vector();
+    let r = Reader::get_root(&builder.view()).unwrap().as_vector();
+    assert_eq!(r.idx(0).as_str(), "foo");
+    assert_eq!(r.idx(1).as_str(), "barrr");
+    assert_eq!(r.idx(2).as_str(), "bazzzzzz");
+}
+
+#[test]
+fn store_13() {
+    let finished = singleton::<i32>(13);
+    let r = Reader::get_root(&finished).unwrap();
+    assert_eq!(r.as_i32(), 13);
+}
+#[test]
+fn singleton_vector_uint_4_16bit() {
+    let mut builder = Builder::default();
+    let mut v = builder.start_vector();
+    v.push(2u8);
+    v.push(3u8);
+    v.push(5u8);
+    v.end_vector();
+    let buf1 = builder.view();
+    let buf2 = singleton(&[2u8, 3, 5]);
+    assert_eq!(buf1, buf2.as_slice());
+
+    let r = Reader::get_root(&buf1).unwrap().as_vector();
+    assert_eq!(r.idx(0).get_u64(), Ok(2));
+    assert_eq!(r.idx(1).get_u64(), Ok(3));
+    assert_eq!(r.idx(2).get_u64(), Ok(5));
+    assert_eq!(r.index(3).unwrap_err(), ReaderError::IndexOutOfBounds);
+}
+#[test]
+fn vector_uint4() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(2u8);
+    v.push(3u8);
+    v.push(5u8);
+    v.push(7u8);
+    v.end_vector();
+    let r = Reader::get_root(&fxb.view()).unwrap();
+    let v = r.as_vector();
+    assert_eq!(v.idx(0).get_u64(), Ok(2));
+    assert_eq!(v.idx(1).get_u64(), Ok(3));
+    assert_eq!(v.idx(2).get_u64(), Ok(5));
+    assert_eq!(v.idx(3).get_u64(), Ok(7));
+    assert!(v.index(4).is_err());
+    #[cfg(target_endian = "little")]
+    {
+        assert_eq!(r.get_slice::<u8>().unwrap(), [2, 3, 5, 7]);
+    }
+}
+#[test]
+fn store_and_read_blob() {
+    let mut fxb = Builder::default();
+    let mut v = fxb.start_vector();
+    v.push(Blob(&[1, 2, 3, 4]));
+    v.push(Blob(&[5, 6, 7]));
+    v.end_vector();
+
+    let r = Reader::get_root(&fxb.view()).unwrap().as_vector();
+    assert_eq!(r.idx(0).get_blob(), Ok(Blob(&[1, 2, 3, 4])));
+    assert_eq!(r.idx(1).get_blob(), Ok(Blob(&[5, 6, 7])));
+}
+#[test]
+fn map_64bit() {
+    let mut fxb = Builder::default();
+    let mut m = fxb.start_map();
+    m.push("a", 257u16);
+    m.push("b", u64::max_value() - 3);
+    m.end_map();
+
+    let r = Reader::get_root(&fxb.view()).unwrap().as_map();
+    assert_eq!(r.idx("a").as_u16(), 257);
+    assert_eq!(r.idx("b").as_u64(), u64::max_value() - 3);
+}
+#[test]
+fn index_map() {
+    let mut fxb = Builder::default();
+    let mut m = fxb.start_map();
+    m.push("foo", 17u8);
+    m.push("bar", 33u16);
+    m.push("baz", 41u32);
+    m.end_map();
+
+    let r = Reader::get_root(fxb.view()).unwrap().as_map();
+    assert_eq!(r.idx(0).get_u64(), Ok(33));
+    assert_eq!(r.idx(1).get_u64(), Ok(41));
+    assert_eq!(r.idx(2).as_u8(), 17);
+    assert_eq!(r.index(3).unwrap_err(), ReaderError::IndexOutOfBounds);
+
+    assert_eq!(r.idx("bar").as_u64(), 33);
+    assert_eq!(r.idx("baz").as_u32(), 41);
+    assert_eq!(r.idx("foo").as_u16(), 17);
+    assert_eq!(r.index("???").unwrap_err(), ReaderError::KeyNotFound);
+}
+
+#[test]
+fn map_strings() {
+    let mut fxb = Builder::default();
+    {
+        let mut m = fxb.start_map();
+        let mut a = m.start_vector("a");
+        for &s in ["b", "c", "d", "e"].iter() {
+            a.push(s);
+        }
+        a.end_vector();
+        let mut f = m.start_vector("f");
+        for &s in ["gh", "ij"].iter() {
+            f.push(s);
+        }
+    }
+    let r = Reader::get_root(fxb.view()).unwrap().as_map();
+    let a = r.idx("a").as_vector();
+
+    assert_eq!(a.idx(0).as_str(), "b");
+    assert_eq!(a.idx(1).as_str(), "c");
+    assert_eq!(a.idx(2).as_str(), "d");
+    assert_eq!(a.idx(3).as_str(), "e");
+
+    let f = r.idx("f").as_vector();
+    assert_eq!(f.idx(0).as_str(), "gh");
+    assert_eq!(f.idx(1).as_str(), "ij");
+
+    // Defaults to empty string for index errors.
+    assert_eq!(r.idx("a").as_vector().idx(4).as_str(), "");
+    assert_eq!(r.idx("b").as_vector().idx(2).as_str(), "");
+    assert_eq!(r.idx("c").as_str(), "");
+}
+
+#[test]
+fn store_u64() {
+    let finished = singleton(u64::max_value() - 10);
+    let r = Reader::get_root(&finished).unwrap();
+    assert_eq!(r.get_u64(), Ok(u64::max_value() - 10));
+}
+#[test]
+fn store_indirects() {
+    let mut b = Builder::default();
+    let mut v = b.start_vector();
+    v.push(IndirectInt(-42));
+    v.push(IndirectUInt(9000));
+    v.push(IndirectFloat(3.14));
+    v.end_vector();
+    let r = Reader::get_root(b.view()).unwrap().as_vector();
+    assert_eq!(r.idx(0).get_i64().unwrap(), -42);
+    assert_eq!(r.idx(1).get_u64().unwrap(), 9000);
+    assert_eq!(r.idx(2).get_f64().unwrap(), 3.14);
+}
+
+#[derive(Serialize, Deserialize, Debug, PartialEq)]
+struct Foo {
+    a: i8,
+    b: f64,
+    c: Vec<u32>,
+    d: String,
+}
+quickcheck! {
+    fn serde_foo(a: i8,
+    b: f64,
+    c: Vec<u32>,
+    d: String) -> bool {
+        let mut s = FlexbufferSerializer::new();
+        let data = Foo { a, b, c, d };
+        data.serialize(&mut s).unwrap();
+
+        let read = Foo::deserialize(Reader::get_root(s.view()).unwrap()).unwrap();
+        data == read
+    }
+}
+
+#[test]
+fn serde_serious() {
+    #[derive(Debug, PartialEq, Serialize, Deserialize)]
+    enum MyEnum {
+        Unit,
+        NewType([i32; 3]),
+        Tuple(f32, f64),
+        Struct { a: u8, b: u16, c: u32 },
+    }
+    #[derive(Debug, PartialEq, Serialize, Deserialize)]
+    struct MyNewType;
+
+    #[derive(Debug, PartialEq, Serialize, Deserialize)]
+    struct MyStruct {
+        a: u8,
+        b: u16,
+        c: u32,
+        d: u64,
+    };
+
+    #[derive(Debug, PartialEq, Serialize, Deserialize)]
+    struct MyUnitStruct(Vec<String>);
+
+    #[derive(Debug, PartialEq, Serialize, Deserialize)]
+    struct MyTupleStruct(MyNewType, MyUnitStruct, MyStruct, Vec<MyEnum>);
+
+    let data = MyTupleStruct(
+        MyNewType,
+        MyUnitStruct(vec!["Hello".to_string(), "World".to_string()]),
+        MyStruct {
+            a: 2,
+            b: 4,
+            c: 8,
+            d: 16,
+        },
+        vec![
+            MyEnum::Unit,
+            MyEnum::NewType([-1, 0, 1]),
+            MyEnum::Unit,
+            MyEnum::Tuple(3.14, 2.71),
+            MyEnum::Struct {
+                a: 32,
+                b: 64,
+                c: 128,
+            },
+        ],
+    );
+
+    let mut s = FlexbufferSerializer::new();
+    data.serialize(&mut s).unwrap();
+
+    let reader = Reader::get_root(s.view()).unwrap();
+    let read = MyTupleStruct::deserialize(reader).unwrap();
+    assert_eq!(data, read);
+}
+#[test]
+fn serialize_serde_with_bytes_as_blob() {
+    #[derive(Serialize, Deserialize)]
+    struct Foo(#[serde(with = "serde_bytes")] Vec<u8>);
+    let mut s = FlexbufferSerializer::new();
+    Foo(vec![5, 6, 7, 8]).serialize(&mut s).unwrap();
+    let reader = Reader::get_root(s.view()).unwrap();
+    assert_eq!(reader.flexbuffer_type(), FlexBufferType::Blob);
+    assert_eq!(reader.as_blob(), Blob(&[5, 6, 7, 8]));
+}
+#[test]
+fn iter() {
+    let mut fxb = Builder::default();
+    {
+        let mut m = fxb.start_map();
+        m.push("a", "42");
+        m.push("b", 250i64);
+        m.push("c", 5000u16);
+    }
+    let r = Reader::get_root(fxb.view()).unwrap();
+
+    let v: Vec<u32> = r.as_vector().iter().map(|x| x.as_u32()).collect();
+    assert_eq!(&v, &[42, 250, 5000]);
+}
+
+#[test]
+fn deserialize_newtype_i8() {
+    #[derive(Deserialize)]
+    struct Foo(u8);
+    let data = [13, 4, 1];
+    let r = Reader::get_root(&data).unwrap();
+    let foo = Foo::deserialize(r).unwrap();
+    assert_eq!(foo.0, 13);
+}
+#[test]
+fn deserialize_newtype_str() {
+    #[derive(Deserialize)]
+    struct Foo<'a>(&'a str);
+    let data = [5, b'h', b'e', b'l', b'l', b'o', b'\0', 6, 5 << 2, 1];
+    let r = Reader::get_root(&data).unwrap();
+    let foo = Foo::deserialize(r).unwrap();
+    assert_eq!(foo.0, "hello");
+}
+#[test]
+#[rustfmt::skip]
+fn deserialize_tuple_struct_to_vec_uint4() {
+    #[derive(Deserialize)]
+    struct Foo(u8, u16, u32, u64);
+    let data = [
+        4, 0, 16, 0, 64, 0, 0, 1, // Data
+        8,              // Vector offset.
+        23 << 2 | 1,    // (VectorUInt4, W16 - referring to data).
+        1,              // Root width W8 - referring to vector.
+    ];
+    let r = Reader::get_root(&data).unwrap();
+    let foo = Foo::deserialize(r).unwrap();
+    assert_eq!(foo.0, 4);
+    assert_eq!(foo.1, 16);
+    assert_eq!(foo.2, 64);
+    assert_eq!(foo.3, 256);
+
+    let data = [
+        1, 2, 3, 4, // The vector.
+        4,          // Root data (offset).
+        23 << 2,    // Root type: VectorUInt4, W8.
+        1,          // Root width: W8.
+    ];
+    let r = Reader::get_root(&data).unwrap();
+    let foo = Foo::deserialize(r).unwrap();
+    assert_eq!(foo.0, 1);
+    assert_eq!(foo.1, 2);
+    assert_eq!(foo.2, 3);
+    assert_eq!(foo.3, 4);
+}
diff --git a/tests/rust_usage_test/tests/integration_test.rs b/tests/rust_usage_test/tests/integration_test.rs
index 0dace96..5957e2c 100644
--- a/tests/rust_usage_test/tests/integration_test.rs
+++ b/tests/rust_usage_test/tests/integration_test.rs
@@ -15,15 +15,39 @@
  * limitations under the License.
  */
 
+#[macro_use]
 extern crate quickcheck;
-
 extern crate flatbuffers;
+extern crate flexbuffers;
+extern crate rand;
+extern crate serde;
+#[macro_use]
+extern crate serde_derive;
+#[macro_use]
+extern crate quickcheck_derive;
 
-#[allow(dead_code, unused_imports)]
+mod flexbuffers_tests;
+mod optional_scalars_test;
+
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
 #[path = "../../monster_test_generated.rs"]
 mod monster_test_generated;
 pub use monster_test_generated::my_game;
 
+#[allow(dead_code, unused_imports)]
+#[path = "../../optional_scalars_generated.rs"]
+mod optional_scalars_generated;
+
+#[rustfmt::skip] // TODO: Use standard rust formatting and remove dead code.
+#[allow(dead_code)]
+mod flatbuffers_tests {
+use super::*;
+
 // Include simple random number generator to ensure results will be the
 // same across platforms.
 // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
@@ -184,6 +208,7 @@
     let inv = m.inventory().unwrap();
     check_eq!(inv.len(), 5)?;
     check_eq!(inv.iter().sum::<u8>(), 10u8)?;
+    check_eq!(inv.iter().rev().sum::<u8>(), 10u8)?;
 
     check_is_some!(m.test4())?;
     let test4 = m.test4().unwrap();
@@ -234,6 +259,45 @@
     fn monster_file_extension() {
         assert_eq!("mon", my_game::example::MONSTER_EXTENSION);
     }
+
+    #[test]
+    fn enum_constants_are_public() {
+        assert_eq!(-1, my_game::example::Race::ENUM_MIN);
+        assert_eq!(2, my_game::example::Race::ENUM_MAX);
+        assert_eq!(my_game::example::Race::ENUM_VALUES, [
+            my_game::example::Race::None,
+            my_game::example::Race::Human,
+            my_game::example::Race::Dwarf,
+            my_game::example::Race::Elf,
+        ]);
+
+        assert_eq!(0, my_game::example::Any::ENUM_MIN);
+        assert_eq!(3, my_game::example::Any::ENUM_MAX);
+        assert_eq!(my_game::example::Any::ENUM_VALUES, [
+            my_game::example::Any::NONE,
+            my_game::example::Any::Monster,
+            my_game::example::Any::TestSimpleTableWithEnum,
+            my_game::example::Any::MyGame_Example2_Monster,
+        ]);
+
+        assert_eq!(0, my_game::example::AnyUniqueAliases::ENUM_MIN);
+        assert_eq!(3, my_game::example::AnyUniqueAliases::ENUM_MAX);
+        assert_eq!(my_game::example::AnyUniqueAliases::ENUM_VALUES, [
+            my_game::example::AnyUniqueAliases::NONE,
+            my_game::example::AnyUniqueAliases::M,
+            my_game::example::AnyUniqueAliases::TS,
+            my_game::example::AnyUniqueAliases::M2,
+        ]);
+
+        assert_eq!(0, my_game::example::AnyAmbiguousAliases::ENUM_MIN);
+        assert_eq!(3, my_game::example::AnyAmbiguousAliases::ENUM_MAX);
+        assert_eq!(my_game::example::AnyAmbiguousAliases::ENUM_VALUES, [
+            my_game::example::AnyAmbiguousAliases::NONE,
+            my_game::example::AnyAmbiguousAliases::M1,
+            my_game::example::AnyAmbiguousAliases::M2,
+            my_game::example::AnyAmbiguousAliases::M3,
+        ]);
+    }
 }
 
 #[cfg(test)]
@@ -509,6 +573,18 @@
         assert_eq!(m.testarrayofstring().unwrap().len(), 2);
         assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
         assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+
+        let rust_vec_inst = m.testarrayofstring().unwrap();
+        let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_collect.len(), 2);
+        assert_eq!(rust_vec_iter_collect[0], "foobar");
+        assert_eq!(rust_vec_iter_collect[1], "baz");
+
+        let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_rev_collect.len(), 2);
+        assert_eq!(rust_vec_iter_rev_collect[1], "foobar");
+        assert_eq!(rust_vec_iter_rev_collect[0], "baz");
+
     }
     #[test]
     fn vector_of_string_store_manual_build() {
@@ -523,6 +599,17 @@
         assert_eq!(m.testarrayofstring().unwrap().len(), 2);
         assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
         assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+
+        let rust_vec_inst = m.testarrayofstring().unwrap();
+        let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_collect.len(), 2);
+        assert_eq!(rust_vec_iter_collect[0], "foobar");
+        assert_eq!(rust_vec_iter_collect[1], "baz");
+
+        let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_rev_collect.len(), 2);
+        assert_eq!(rust_vec_iter_rev_collect[0], "baz");
+        assert_eq!(rust_vec_iter_rev_collect[1], "foobar");
     }
     #[test]
     fn vector_of_ubyte_store() {
@@ -543,6 +630,13 @@
             name: Some(name),
             testarrayofbools: Some(v), ..Default::default()});
         assert_eq!(m.testarrayofbools().unwrap(), &[false, true, false, true][..]);
+
+        let rust_vec_inst = m.testarrayofbools().unwrap();
+        let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_collect, &[&false, &true, &false, &true][..]);
+
+        let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_rev_collect, &[&true, &false, &true, &false][..]);
     }
     #[test]
     fn vector_of_f64_store() {
@@ -554,6 +648,15 @@
             vector_of_doubles: Some(v), ..Default::default()});
         assert_eq!(m.vector_of_doubles().unwrap().len(), 1);
         assert_eq!(m.vector_of_doubles().unwrap().get(0), 3.14159265359f64);
+
+        let rust_vec_inst = m.vector_of_doubles().unwrap();
+        let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_collect.len(), 1);
+        assert_eq!(rust_vec_iter_collect[0], 3.14159265359f64);
+
+        let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_rev_collect.len(), 1);
+        assert_eq!(rust_vec_iter_rev_collect[0], 3.14159265359f64);
     }
     #[test]
     fn vector_of_struct_store() {
@@ -564,6 +667,13 @@
             name: Some(name),
             test4: Some(v), ..Default::default()});
         assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
+
+        let rust_vec_inst = m.test4().unwrap();
+        let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_collect, &[&my_game::example::Test::new(127, -128), &my_game::example::Test::new(3, 123)][..]);
+
+        let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_rev_collect, &[&my_game::example::Test::new(3, 123), &my_game::example::Test::new(127, -128)][..]);
     }
     #[test]
     fn vector_of_struct_store_with_type_inference() {
@@ -577,19 +687,18 @@
             test4: Some(v), ..Default::default()});
         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)][..]);
     }
-    // TODO(rw) this passes, but I don't want to change the monster test schema right now
-    // #[test]
-    // fn vector_of_enum_store() {
-    //     let mut b = flatbuffers::FlatBufferBuilder::new();
-    //     let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]);
-    //     let name = b.create_string("foo");
-    //     let m = build_mon(&mut b, &my_game::example::MonsterArgs{
-    //         name: Some(name),
-    //         vector_of_enum: Some(v), ..Default::default()});
-    //     assert_eq!(m.vector_of_enum().unwrap().len(), 2);
-    //     assert_eq!(m.vector_of_enum().unwrap().get(0), my_game::example::Color::Red);
-    //     assert_eq!(m.vector_of_enum().unwrap().get(1), my_game::example::Color::Green);
-    // }
+     #[test]
+     fn vector_of_enums_store() {
+         let mut b = flatbuffers::FlatBufferBuilder::new();
+         let v = b.create_vector::<my_game::example::Color>(&[my_game::example::Color::Red, my_game::example::Color::Green][..]);
+         let name = b.create_string("foo");
+         let m = build_mon(&mut b, &my_game::example::MonsterArgs{
+             name: Some(name),
+             vector_of_enums: Some(v), ..Default::default()});
+         assert_eq!(m.vector_of_enums().unwrap().len(), 2);
+         assert_eq!(m.vector_of_enums().unwrap().get(0), my_game::example::Color::Red);
+         assert_eq!(m.vector_of_enums().unwrap().get(1), my_game::example::Color::Green);
+     }
     #[test]
     fn vector_of_table_store() {
         let b = &mut flatbuffers::FlatBufferBuilder::new();
@@ -613,6 +722,21 @@
         assert_eq!(m.testarrayoftables().unwrap().get(0).name(), "foo");
         assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100);
         assert_eq!(m.testarrayoftables().unwrap().get(1).name(), "bar");
+
+        let rust_vec_inst = m.testarrayoftables().unwrap();
+        let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_collect.len(), 2);
+        assert_eq!(rust_vec_iter_collect[0].hp(), 55);
+        assert_eq!(rust_vec_iter_collect[0].name(), "foo");
+        assert_eq!(rust_vec_iter_collect[1].hp(), 100);
+        assert_eq!(rust_vec_iter_collect[1].name(), "bar");
+
+        let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+        assert_eq!(rust_vec_iter_rev_collect.len(), 2);
+        assert_eq!(rust_vec_iter_rev_collect[0].hp(), 100);
+        assert_eq!(rust_vec_iter_rev_collect[0].name(), "bar");
+        assert_eq!(rust_vec_iter_rev_collect[1].hp(), 55);
+        assert_eq!(rust_vec_iter_rev_collect[1].name(), "foo");
     }
 }
 
@@ -721,6 +845,12 @@
             let aln = ::std::mem::align_of::<my_game::example::Ability>();
             assert_eq!((a_ptr - start_ptr) % aln, 0);
         }
+        for a in abilities.iter().rev() {
+            let a_ptr = a as *const my_game::example::Ability as usize;
+            assert!(a_ptr > start_ptr);
+            let aln = ::std::mem::align_of::<my_game::example::Ability>();
+            assert_eq!((a_ptr - start_ptr) % aln, 0);
+        }
     }
 }
 
@@ -765,10 +895,12 @@
         assert_eq!(x, back_again);
     }
 
-    #[test]
-    fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
-    #[test]
-    fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
+    // TODO(rw): Replace the implementations with the new stdlib endian-conversion functions.
+    // TODO(rw): Re-enable these tests (currently, rare CI failures occur that seem spurious).
+    // #[test]
+    // fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
+    // #[test]
+    // fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
 }
 
 #[cfg(test)]
@@ -806,6 +938,13 @@
                 result_vec.push(got.get(i));
             }
             assert_eq!(result_vec, xs);
+
+            let rust_vec_iter = got.iter().collect::<Vec<T>>();
+            assert_eq!(rust_vec_iter, xs);
+
+            let mut rust_vec_rev_iter = got.iter().rev().collect::<Vec<T>>();
+            rust_vec_rev_iter.reverse();
+            assert_eq!(rust_vec_rev_iter, xs);
         }
 
         #[test]
@@ -1394,6 +1533,58 @@
     }
 
     #[test]
+    fn generated_code_debug_prints_correctly() {
+        let b = &mut flatbuffers::FlatBufferBuilder::new();
+        create_serialized_example_with_generated_code(b);
+        let buf = b.finished_data();
+        serialized_example_is_accessible_and_correct(&buf, true, false).unwrap();
+        let m = super::my_game::example::get_root_as_monster(buf);
+        assert_eq!(
+            format!("{:.5?}", &m),
+            "Monster { pos: Some(Vec3 { x: 1.00000, y: 2.00000, z: 3.00000, \
+            test1: 3.00000, test2: Green, test3: Test { a: 5, b: 6 } }), \
+            mana: 150, hp: 80, name: \"MyMonster\", \
+            inventory: Some([0, 1, 2, 3, 4]), color: Blue, test_type: Monster, \
+            test: Monster { pos: None, mana: 150, hp: 100, name: \"Fred\", \
+            inventory: None, color: Blue, test_type: NONE, test: None, \
+            test4: None, testarrayofstring: None, testarrayoftables: None, \
+            enemy: None, testnestedflatbuffer: None, testempty: None, \
+            testbool: false, testhashs32_fnv1: 0, testhashu32_fnv1: 0, \
+            testhashs64_fnv1: 0, testhashu64_fnv1: 0, testhashs32_fnv1a: 0, \
+            testhashu32_fnv1a: 0, testhashs64_fnv1a: 0, testhashu64_fnv1a: 0, \
+            testarrayofbools: None, testf: 3.14159, testf2: 3.00000, testf3: 0.00000, \
+            testarrayofstring2: None, testarrayofsortedstruct: None, flex: None, \
+            test5: None, vector_of_longs: None, vector_of_doubles: None, \
+            parent_namespace_test: None, vector_of_referrables: None, \
+            single_weak_reference: 0, vector_of_weak_references: None, \
+            vector_of_strong_referrables: None, co_owning_reference: 0, \
+            vector_of_co_owning_references: None, non_owning_reference: 0, \
+            vector_of_non_owning_references: None, any_unique_type: NONE, \
+            any_unique: None, any_ambiguous_type: NONE, any_ambiguous: None, \
+            vector_of_enums: None, signed_enum: None, \
+            testrequirednestedflatbuffer: None }, test4: Some([Test { \
+            a: 10, b: 20 }, Test { a: 30, b: 40 }]), \
+            testarrayofstring: Some([\"test1\", \"test2\"]), \
+            testarrayoftables: None, enemy: None, testnestedflatbuffer: None, \
+            testempty: None, testbool: false, testhashs32_fnv1: 0, \
+            testhashu32_fnv1: 0, testhashs64_fnv1: 0, testhashu64_fnv1: 0, \
+            testhashs32_fnv1a: 0, testhashu32_fnv1a: 0, testhashs64_fnv1a: 0, \
+            testhashu64_fnv1a: 0, testarrayofbools: None, testf: 3.14159, \
+            testf2: 3.00000, testf3: 0.00000, testarrayofstring2: None, \
+            testarrayofsortedstruct: None, flex: None, test5: None, \
+            vector_of_longs: None, vector_of_doubles: None, \
+            parent_namespace_test: None, vector_of_referrables: None, \
+            single_weak_reference: 0, vector_of_weak_references: None, \
+            vector_of_strong_referrables: None, co_owning_reference: 0, \
+            vector_of_co_owning_references: None, non_owning_reference: 0, \
+            vector_of_non_owning_references: None, any_unique_type: NONE, \
+            any_unique: None, any_ambiguous_type: NONE, any_ambiguous: None, \
+            vector_of_enums: None, signed_enum: None, \
+            testrequirednestedflatbuffer: None }"
+        );
+    }
+
+    #[test]
     fn generated_code_creates_correct_example_repeatedly_with_reset() {
         let b = &mut flatbuffers::FlatBufferBuilder::new();
         for _ in 0..100 {
@@ -2281,6 +2472,25 @@
     }
 
     #[test]
+    fn layout_09b_vtable_with_one_default_bool_force_defaults() {
+        let mut b = flatbuffers::FlatBufferBuilder::new();
+        check(&b, &[]);
+        let off = b.start_table();
+        check(&b, &[]);
+        b.force_defaults(true);
+        b.push_slot(fi2fo(0), false, false);
+        b.end_table(off);
+        check(&b, &[
+            6, 0, // vtable bytes
+            8, 0, // length of object including vtable offset
+            7, 0, // start of bool value
+            6, 0, 0, 0, // offset for start of vtable (int32)
+            0, 0, 0, // padded to 4 bytes
+            0, // bool value
+      ]);
+    }
+
+    #[test]
     fn layout_10_vtable_with_one_int16() {
         let mut b = flatbuffers::FlatBufferBuilder::new();
         check(&b, &[]);
@@ -2694,6 +2904,33 @@
     }
 }
 
+#[cfg(test)]
+mod copy_clone_traits {
+    #[test]
+    fn follow_types_implement_copy_and_clone() {
+        static_assertions::assert_impl_all!(flatbuffers::WIPOffset<u32>: Copy, Clone);
+        static_assertions::assert_impl_all!(flatbuffers::WIPOffset<Vec<u32>>: Copy, Clone);
+
+        static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<u32>: Copy, Clone);
+        static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<Vec<u32>>: Copy, Clone);
+
+        static_assertions::assert_impl_all!(flatbuffers::Vector<'static, u32>: Copy, Clone);
+        static_assertions::assert_impl_all!(flatbuffers::Vector<'static, Vec<u32>>: Copy, Clone);
+    }
+}
+
+#[cfg(test)]
+mod fully_qualified_name {
+    #[test]
+    fn fully_qualified_name_generated() {
+        assert!(check_eq!(::my_game::example::Monster::get_fully_qualified_name(), "MyGame.Example.Monster").is_ok());
+        assert!(check_eq!(::my_game::example_2::Monster::get_fully_qualified_name(), "MyGame.Example2.Monster").is_ok());
+
+        assert!(check_eq!(::my_game::example::Vec3::get_fully_qualified_name(), "MyGame.Example.Vec3").is_ok());
+        assert!(check_eq!(::my_game::example::Ability::get_fully_qualified_name(), "MyGame.Example.Ability").is_ok());
+    }
+}
+
 // this is not technically a test, but we want to always keep this generated
 // file up-to-date, and the simplest way to do that is to make sure that when
 // tests are run, the file is generated.
@@ -2714,3 +2951,4 @@
     f.read_to_end(&mut buf)?;
     Ok(buf)
 }
+}
diff --git a/tests/rust_usage_test/tests/optional_scalars_test.rs b/tests/rust_usage_test/tests/optional_scalars_test.rs
new file mode 100644
index 0000000..f029d03
--- /dev/null
+++ b/tests/rust_usage_test/tests/optional_scalars_test.rs
@@ -0,0 +1,87 @@
+#[allow(dead_code, unused_imports)]
+#[path = "../../optional_scalars_generated.rs"]
+mod optional_scalars_generated;
+use crate::optional_scalars_generated::optional_scalars::*;
+
+// There are 3 variants of scalars in tables - those specified with default=42,
+// optional scalars, and those with nothing specified (implicitly default=0).
+// This tests that you can read what you write.
+macro_rules! make_test {
+    (
+        $test_name: ident,
+        $just: ident, $default: ident, $maybe: ident,
+        $five: expr, $zero: expr, $fortytwo: expr
+    ) => {
+        #[test]
+        fn $test_name() {
+            let mut builder = flatbuffers::FlatBufferBuilder::new();
+            // Test five makes sense when specified.
+            let ss = ScalarStuff::create(
+                &mut builder,
+                &ScalarStuffArgs {
+                    $just: $five,
+                    $default: $five,
+                    $maybe: Some($five),
+                    ..Default::default()
+                },
+            );
+            builder.finish(ss, None);
+
+            let s = flatbuffers::get_root::<ScalarStuff>(builder.finished_data());
+            assert_eq!(s.$just(), $five);
+            assert_eq!(s.$default(), $five);
+            assert_eq!(s.$maybe(), Some($five));
+
+            // Test defaults are used when not specified.
+            let s = flatbuffers::get_root::<ScalarStuff>(&[0; 8]);
+            assert_eq!(s.$just(), $zero);
+            assert_eq!(s.$default(), $fortytwo);
+            assert_eq!(s.$maybe(), None);
+        }
+    };
+}
+
+make_test!(optional_i8, just_i8, default_i8, maybe_i8, 5, 0, 42);
+make_test!(optional_u8, just_u8, default_u8, maybe_u8, 5, 0, 42);
+make_test!(optional_i16, just_i16, default_i16, maybe_i16, 5, 0, 42);
+make_test!(optional_u16, just_u16, default_u16, maybe_u16, 5, 0, 42);
+make_test!(optional_i32, just_i32, default_i32, maybe_i32, 5, 0, 42);
+make_test!(optional_u32, just_u32, default_u32, maybe_u32, 5, 0, 42);
+make_test!(optional_i64, just_i64, default_i64, maybe_i64, 5, 0, 42);
+make_test!(optional_u64, just_u64, default_u64, maybe_u64, 5, 0, 42);
+make_test!(
+    optional_f32,
+    just_f32,
+    default_f32,
+    maybe_f32,
+    5.0,
+    0.0,
+    42.0
+);
+make_test!(
+    optional_f64,
+    just_f64,
+    default_f64,
+    maybe_f64,
+    5.0,
+    0.0,
+    42.0
+);
+make_test!(
+    optional_bool,
+    just_bool,
+    default_bool,
+    maybe_bool,
+    true,
+    false,
+    true
+);
+make_test!(
+     optional_enum,
+     just_enum,
+     default_enum,
+     maybe_enum,
+     OptionalByte::Two,
+     OptionalByte::None,
+     OptionalByte::One
+);