xref: /aosp_15_r20/external/flatbuffers/samples/sample_binary.rs (revision 890232f25432b36107d06881e0a25aaa6b473652)
1*890232f2SAndroid Build Coastguard Worker /*
2*890232f2SAndroid Build Coastguard Worker  * Copyright 2018 Google Inc. All rights reserved.
3*890232f2SAndroid Build Coastguard Worker  *
4*890232f2SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*890232f2SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*890232f2SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*890232f2SAndroid Build Coastguard Worker  *
8*890232f2SAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*890232f2SAndroid Build Coastguard Worker  *
10*890232f2SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*890232f2SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*890232f2SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*890232f2SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*890232f2SAndroid Build Coastguard Worker  * limitations under the License.
15*890232f2SAndroid Build Coastguard Worker  */
16*890232f2SAndroid Build Coastguard Worker 
17*890232f2SAndroid Build Coastguard Worker // import the flatbuffers runtime library
18*890232f2SAndroid Build Coastguard Worker extern crate flatbuffers;
19*890232f2SAndroid Build Coastguard Worker 
20*890232f2SAndroid Build Coastguard Worker // import the generated code
21*890232f2SAndroid Build Coastguard Worker #[allow(dead_code, unused_imports)]
22*890232f2SAndroid Build Coastguard Worker #[allow(clippy::approx_constant)]  // We use low precision PI as a default value.
23*890232f2SAndroid Build Coastguard Worker mod rust_generated;
24*890232f2SAndroid Build Coastguard Worker pub use rust_generated::my_game::sample::{Color, Equipment,
25*890232f2SAndroid Build Coastguard Worker                                              Monster, MonsterArgs,
26*890232f2SAndroid Build Coastguard Worker                                              Vec3,
27*890232f2SAndroid Build Coastguard Worker                                              Weapon, WeaponArgs};
28*890232f2SAndroid Build Coastguard Worker 
29*890232f2SAndroid Build Coastguard Worker 
30*890232f2SAndroid Build Coastguard Worker // Example how to use FlatBuffers to create and read binary buffers.
31*890232f2SAndroid Build Coastguard Worker #[allow(clippy::float_cmp)]
main()32*890232f2SAndroid Build Coastguard Worker fn main() {
33*890232f2SAndroid Build Coastguard Worker   // Build up a serialized buffer algorithmically.
34*890232f2SAndroid Build Coastguard Worker   // Initialize it with a capacity of 1024 bytes.
35*890232f2SAndroid Build Coastguard Worker   let mut builder = flatbuffers::FlatBufferBuilder::with_capacity(1024);
36*890232f2SAndroid Build Coastguard Worker 
37*890232f2SAndroid Build Coastguard Worker   // Serialize some weapons for the Monster: A 'sword' and an 'axe'.
38*890232f2SAndroid Build Coastguard Worker   let weapon_one_name = builder.create_string("Sword");
39*890232f2SAndroid Build Coastguard Worker   let weapon_two_name = builder.create_string("Axe");
40*890232f2SAndroid Build Coastguard Worker 
41*890232f2SAndroid Build Coastguard Worker   // Use the `Weapon::create` shortcut to create Weapons with named field
42*890232f2SAndroid Build Coastguard Worker   // arguments.
43*890232f2SAndroid Build Coastguard Worker   let sword = Weapon::create(&mut builder, &WeaponArgs{
44*890232f2SAndroid Build Coastguard Worker       name: Some(weapon_one_name),
45*890232f2SAndroid Build Coastguard Worker       damage: 3,
46*890232f2SAndroid Build Coastguard Worker   });
47*890232f2SAndroid Build Coastguard Worker   let axe = Weapon::create(&mut builder, &WeaponArgs{
48*890232f2SAndroid Build Coastguard Worker       name: Some(weapon_two_name),
49*890232f2SAndroid Build Coastguard Worker       damage: 5,
50*890232f2SAndroid Build Coastguard Worker   });
51*890232f2SAndroid Build Coastguard Worker 
52*890232f2SAndroid Build Coastguard Worker   // Name of the Monster.
53*890232f2SAndroid Build Coastguard Worker   let name = builder.create_string("Orc");
54*890232f2SAndroid Build Coastguard Worker 
55*890232f2SAndroid Build Coastguard Worker   // Inventory.
56*890232f2SAndroid Build Coastguard Worker   let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
57*890232f2SAndroid Build Coastguard Worker 
58*890232f2SAndroid Build Coastguard Worker   // Create a FlatBuffer `vector` that contains offsets to the sword and axe
59*890232f2SAndroid Build Coastguard Worker   // we created above.
60*890232f2SAndroid Build Coastguard Worker   let weapons = builder.create_vector(&[sword, axe]);
61*890232f2SAndroid Build Coastguard Worker 
62*890232f2SAndroid Build Coastguard Worker   // Create the path vector of Vec3 objects:
63*890232f2SAndroid Build Coastguard Worker   //let x = Vec3::new(1.0, 2.0, 3.0);
64*890232f2SAndroid Build Coastguard Worker   //let y = Vec3::new(4.0, 5.0, 6.0);
65*890232f2SAndroid Build Coastguard Worker   //let path = builder.create_vector(&[x, y]);
66*890232f2SAndroid Build Coastguard Worker 
67*890232f2SAndroid Build Coastguard Worker   // Note that, for convenience, it is also valid to create a vector of
68*890232f2SAndroid Build Coastguard Worker   // references to structs, like this:
69*890232f2SAndroid Build Coastguard Worker   // let path = builder.create_vector(&[&x, &y]);
70*890232f2SAndroid Build Coastguard Worker 
71*890232f2SAndroid Build Coastguard Worker   // Create the monster using the `Monster::create` helper function. This
72*890232f2SAndroid Build Coastguard Worker   // function accepts a `MonsterArgs` struct, which supplies all of the data
73*890232f2SAndroid Build Coastguard Worker   // needed to build a `Monster`. To supply empty/default fields, just use the
74*890232f2SAndroid Build Coastguard Worker   // Rust built-in `Default::default()` function, as demonstrated below.
75*890232f2SAndroid Build Coastguard Worker   let orc = Monster::create(&mut builder, &MonsterArgs{
76*890232f2SAndroid Build Coastguard Worker       pos: Some(&Vec3::new(1.0f32, 2.0f32, 3.0f32)),
77*890232f2SAndroid Build Coastguard Worker       mana: 150,
78*890232f2SAndroid Build Coastguard Worker       hp: 80,
79*890232f2SAndroid Build Coastguard Worker       name: Some(name),
80*890232f2SAndroid Build Coastguard Worker       inventory: Some(inventory),
81*890232f2SAndroid Build Coastguard Worker       color: Color::Red,
82*890232f2SAndroid Build Coastguard Worker       weapons: Some(weapons),
83*890232f2SAndroid Build Coastguard Worker       equipped_type: Equipment::Weapon,
84*890232f2SAndroid Build Coastguard Worker       equipped: Some(axe.as_union_value()),
85*890232f2SAndroid Build Coastguard Worker       //path: Some(path),
86*890232f2SAndroid Build Coastguard Worker       ..Default::default()
87*890232f2SAndroid Build Coastguard Worker   });
88*890232f2SAndroid Build Coastguard Worker 
89*890232f2SAndroid Build Coastguard Worker   // Serialize the root of the object, without providing a file identifier.
90*890232f2SAndroid Build Coastguard Worker   builder.finish(orc, None);
91*890232f2SAndroid Build Coastguard Worker 
92*890232f2SAndroid Build Coastguard Worker   // We now have a FlatBuffer we can store on disk or send over a network.
93*890232f2SAndroid Build Coastguard Worker 
94*890232f2SAndroid Build Coastguard Worker   // ** file/network code goes here :) **
95*890232f2SAndroid Build Coastguard Worker 
96*890232f2SAndroid Build Coastguard Worker   // Instead, we're going to access it right away (as if we just received it).
97*890232f2SAndroid Build Coastguard Worker   // This must be called after `finish()`.
98*890232f2SAndroid Build Coastguard Worker   let buf = builder.finished_data(); // Of type `&[u8]`
99*890232f2SAndroid Build Coastguard Worker 
100*890232f2SAndroid Build Coastguard Worker   // Get access to the root:
101*890232f2SAndroid Build Coastguard Worker   let monster = flatbuffers::root::<Monster>(buf).unwrap();
102*890232f2SAndroid Build Coastguard Worker 
103*890232f2SAndroid Build Coastguard Worker   // Get and test some scalar types from the FlatBuffer.
104*890232f2SAndroid Build Coastguard Worker   let hp = monster.hp();
105*890232f2SAndroid Build Coastguard Worker   let mana = monster.mana();
106*890232f2SAndroid Build Coastguard Worker   let name = monster.name();
107*890232f2SAndroid Build Coastguard Worker 
108*890232f2SAndroid Build Coastguard Worker   assert_eq!(hp, 80);
109*890232f2SAndroid Build Coastguard Worker   assert_eq!(mana, 150);  // default
110*890232f2SAndroid Build Coastguard Worker   assert_eq!(name, Some("Orc"));
111*890232f2SAndroid Build Coastguard Worker 
112*890232f2SAndroid Build Coastguard Worker   // Get and test a field of the FlatBuffer's `struct`.
113*890232f2SAndroid Build Coastguard Worker   assert!(monster.pos().is_some());
114*890232f2SAndroid Build Coastguard Worker   let pos = monster.pos().unwrap();
115*890232f2SAndroid Build Coastguard Worker   let x = pos.x();
116*890232f2SAndroid Build Coastguard Worker   let y = pos.y();
117*890232f2SAndroid Build Coastguard Worker   let z = pos.z();
118*890232f2SAndroid Build Coastguard Worker   assert_eq!(x, 1.0f32);
119*890232f2SAndroid Build Coastguard Worker   assert_eq!(y, 2.0f32);
120*890232f2SAndroid Build Coastguard Worker   assert_eq!(z, 3.0f32);
121*890232f2SAndroid Build Coastguard Worker 
122*890232f2SAndroid Build Coastguard Worker   // Get an element from the `inventory` FlatBuffer's `vector`.
123*890232f2SAndroid Build Coastguard Worker   assert!(monster.inventory().is_some());
124*890232f2SAndroid Build Coastguard Worker   let inv = monster.inventory().unwrap();
125*890232f2SAndroid Build Coastguard Worker 
126*890232f2SAndroid Build Coastguard Worker   // Note that this vector is returned as a slice, because direct access for
127*890232f2SAndroid Build Coastguard Worker   // this type, a u8 vector, is safe on all platforms:
128*890232f2SAndroid Build Coastguard Worker   let third_item = inv[2];
129*890232f2SAndroid Build Coastguard Worker   assert_eq!(third_item, 2);
130*890232f2SAndroid Build Coastguard Worker 
131*890232f2SAndroid Build Coastguard Worker   // Get and test the `weapons` FlatBuffers's `vector`.
132*890232f2SAndroid Build Coastguard Worker   assert!(monster.weapons().is_some());
133*890232f2SAndroid Build Coastguard Worker   let weps = monster.weapons().unwrap();
134*890232f2SAndroid Build Coastguard Worker   //let weps_len = weps.len();
135*890232f2SAndroid Build Coastguard Worker   let wep2 = weps.get(1);
136*890232f2SAndroid Build Coastguard Worker   let second_weapon_name = wep2.name();
137*890232f2SAndroid Build Coastguard Worker   let second_weapon_damage = wep2.damage();
138*890232f2SAndroid Build Coastguard Worker   assert_eq!(second_weapon_name, Some("Axe"));
139*890232f2SAndroid Build Coastguard Worker   assert_eq!(second_weapon_damage, 5);
140*890232f2SAndroid Build Coastguard Worker 
141*890232f2SAndroid Build Coastguard Worker   // Get and test the `Equipment` union (`equipped` field).
142*890232f2SAndroid Build Coastguard Worker   assert_eq!(monster.equipped_type(), Equipment::Weapon);
143*890232f2SAndroid Build Coastguard Worker   let equipped = monster.equipped_as_weapon().unwrap();
144*890232f2SAndroid Build Coastguard Worker   let weapon_name = equipped.name();
145*890232f2SAndroid Build Coastguard Worker   let weapon_damage = equipped.damage();
146*890232f2SAndroid Build Coastguard Worker   assert_eq!(weapon_name, Some("Axe"));
147*890232f2SAndroid Build Coastguard Worker   assert_eq!(weapon_damage, 5);
148*890232f2SAndroid Build Coastguard Worker 
149*890232f2SAndroid Build Coastguard Worker   // Get and test the `path` FlatBuffers's `vector`.
150*890232f2SAndroid Build Coastguard Worker   //assert_eq!(monster.path().unwrap().len(), 2);
151*890232f2SAndroid Build Coastguard Worker   //assert_eq!(monster.path().unwrap()[0].x(), 1.0);
152*890232f2SAndroid Build Coastguard Worker   //assert_eq!(monster.path().unwrap()[1].x(), 4.0);
153*890232f2SAndroid Build Coastguard Worker 
154*890232f2SAndroid Build Coastguard Worker   println!("The FlatBuffer was successfully created and accessed!");
155*890232f2SAndroid Build Coastguard Worker   dbg!(monster);
156*890232f2SAndroid Build Coastguard Worker }
157*890232f2SAndroid Build Coastguard Worker 
158*890232f2SAndroid Build Coastguard Worker #[cfg(test)]
159*890232f2SAndroid Build Coastguard Worker #[test]
test_main()160*890232f2SAndroid Build Coastguard Worker fn test_main() {
161*890232f2SAndroid Build Coastguard Worker     main()
162*890232f2SAndroid Build Coastguard Worker }
163