rlbot-flatbuffers 0.14.5__tar.gz → 0.14.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/Cargo.lock +7 -7
  2. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/Cargo.toml +1 -1
  3. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/PKG-INFO +1 -1
  4. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/enums.rs +17 -67
  5. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/main.rs +10 -30
  6. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/pyi.rs +23 -39
  7. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/structs.rs +122 -218
  8. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/unions.rs +11 -54
  9. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/src/lib.rs +3 -15
  10. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/LICENSE +0 -0
  11. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/README.md +0 -0
  12. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/class_inject.rs +0 -0
  13. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/codegen/generator.rs +0 -0
  14. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/FLATBUFFERS-LICENSE +0 -0
  15. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/README.md +0 -0
  16. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/comms.fbs +0 -0
  17. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/flatc +0 -0
  18. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/flatc.exe +0 -0
  19. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/gamedata.fbs +0 -0
  20. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/gamestatemanip.fbs +0 -0
  21. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/matchconfig.fbs +0 -0
  22. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/rendering.fbs +0 -0
  23. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/flatbuffers-schema/rlbot.fbs +0 -0
  24. {rlbot_flatbuffers-0.14.5 → rlbot_flatbuffers-0.14.6}/pyproject.toml +0 -0
@@ -115,9 +115,9 @@ checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8"
115
115
 
116
116
  [[package]]
117
117
  name = "libc"
118
- version = "0.2.170"
118
+ version = "0.2.171"
119
119
  source = "registry+https://github.com/rust-lang/crates.io-index"
120
- checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
120
+ checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
121
121
 
122
122
  [[package]]
123
123
  name = "manyhow"
@@ -153,9 +153,9 @@ dependencies = [
153
153
 
154
154
  [[package]]
155
155
  name = "once_cell"
156
- version = "1.20.3"
156
+ version = "1.21.1"
157
157
  source = "registry+https://github.com/rust-lang/crates.io-index"
158
- checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
158
+ checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
159
159
 
160
160
  [[package]]
161
161
  name = "portable-atomic"
@@ -248,9 +248,9 @@ dependencies = [
248
248
 
249
249
  [[package]]
250
250
  name = "quote"
251
- version = "1.0.39"
251
+ version = "1.0.40"
252
252
  source = "registry+https://github.com/rust-lang/crates.io-index"
253
- checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801"
253
+ checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
254
254
  dependencies = [
255
255
  "proc-macro2",
256
256
  ]
@@ -279,7 +279,7 @@ dependencies = [
279
279
 
280
280
  [[package]]
281
281
  name = "rlbot_flatbuffers"
282
- version = "0.14.5"
282
+ version = "0.14.6"
283
283
  dependencies = [
284
284
  "flatbuffers",
285
285
  "get-size",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rlbot_flatbuffers"
3
- version = "0.14.5"
3
+ version = "0.14.6"
4
4
  edition = "2024"
5
5
  description = "A Python module implemented in Rust for serializing and deserializing RLBot's flatbuffers"
6
6
  repository = "https://github.com/VirxEC/rlbot_flatbuffers_py"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rlbot_flatbuffers
3
- Version: 0.14.5
3
+ Version: 0.14.6
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -16,10 +16,7 @@ fn camel_to_snake_case(variable_name: &str) -> String {
16
16
  for c in variable_name.chars() {
17
17
  if c.is_uppercase() {
18
18
  if last_was_uppercase {
19
- snake_case_parts
20
- .last_mut()
21
- .unwrap()
22
- .push(c.to_lowercase().next().unwrap());
19
+ snake_case_parts.last_mut().unwrap().push(c.to_lowercase().next().unwrap());
23
20
  } else {
24
21
  snake_case_parts.push(c.to_lowercase().to_string());
25
22
  }
@@ -80,9 +77,7 @@ impl EnumBindGenerator {
80
77
  })
81
78
  }
82
79
 
83
- pub fn raw_types_to_custom(
84
- raw_types: Vec<(&str, &str, Option<Vec<String>>)>,
85
- ) -> Vec<CustomEnumType> {
80
+ pub fn raw_types_to_custom(raw_types: Vec<(&str, &str, Option<Vec<String>>)>) -> Vec<CustomEnumType> {
86
81
  raw_types
87
82
  .into_iter()
88
83
  .map(|(name, raw_type, doc_str)| CustomEnumType {
@@ -129,17 +124,12 @@ impl EnumBindGenerator {
129
124
  continue;
130
125
  }
131
126
 
132
- let definition = line_trim
133
- .trim_start_matches("pub const ")
134
- .trim_end_matches(';');
127
+ let definition = line_trim.trim_start_matches("pub const ").trim_end_matches(';');
135
128
 
136
129
  let mut parts = definition.split(": Self = ");
137
130
 
138
131
  let variable_name = parts.next()?;
139
- let variable_value = parts
140
- .next()?
141
- .trim_start_matches("Self(")
142
- .trim_end_matches(')');
132
+ let variable_value = parts.next()?.trim_start_matches("Self(").trim_end_matches(')');
143
133
 
144
134
  let docs = if docs.is_empty() {
145
135
  None
@@ -169,14 +159,11 @@ impl EnumBindGenerator {
169
159
  let union_end_definition = "}\n";
170
160
  let union_end = contents[union_start..].find(union_end_definition).unwrap();
171
161
 
172
- let union_definition = &contents[union_start + union_definition.len()
173
- ..union_start + union_end - union_end_definition.len()];
162
+ let union_definition =
163
+ &contents[union_start + union_definition.len()..union_start + union_end - union_end_definition.len()];
174
164
 
175
165
  for (line, variable) in union_definition.split('\n').zip(&mut custom_types) {
176
- let line_trim = line
177
- .trim()
178
- .trim_start_matches(&variable.name)
179
- .trim_end_matches(',');
166
+ let line_trim = line.trim().trim_start_matches(&variable.name).trim_end_matches(',');
180
167
 
181
168
  if line_trim.is_empty() {
182
169
  variable.value = None;
@@ -185,9 +172,7 @@ impl EnumBindGenerator {
185
172
 
186
173
  variable.snake_case_name = camel_to_snake_case(variable.name.as_str());
187
174
 
188
- let new_type = line_trim
189
- .trim_start_matches("(Box<")
190
- .trim_end_matches("T>)");
175
+ let new_type = line_trim.trim_start_matches("(Box<").trim_end_matches("T>)");
191
176
  variable.value = Some(new_type.to_string());
192
177
  }
193
178
 
@@ -204,11 +189,7 @@ impl EnumBindGenerator {
204
189
 
205
190
  for variable_info in &self.types {
206
191
  let variable_name = variable_info.name.as_str();
207
- write_fmt!(
208
- self,
209
- " {} => Ok(Self::{variable_name}),",
210
- variable_info.raw_type
211
- );
192
+ write_fmt!(self, " {} => Ok(Self::{variable_name}),", variable_info.raw_type);
212
193
  }
213
194
 
214
195
  if self.types.len() != usize::from(u8::MAX) {
@@ -256,10 +237,7 @@ impl Generator for EnumBindGenerator {
256
237
  contents = contents.replace("\r\n", "\n");
257
238
  }
258
239
 
259
- contents = contents.replace(
260
- "use self::flatbuffers",
261
- "use get_size::GetSize;\nuse self::flatbuffers",
262
- );
240
+ contents = contents.replace("use self::flatbuffers", "use get_size::GetSize;\nuse self::flatbuffers");
263
241
 
264
242
  contents = contents.replace(
265
243
  "#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]\n",
@@ -288,14 +266,8 @@ impl Generator for EnumBindGenerator {
288
266
 
289
267
  fn generate_definition(&mut self) {
290
268
  write_str!(self, "#[allow(non_camel_case_types)]");
291
- write_str!(
292
- self,
293
- "#[pyclass(module = \"rlbot_flatbuffers\", frozen, hash, eq, eq_int)]"
294
- );
295
- write_str!(
296
- self,
297
- "#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]"
298
- );
269
+ write_str!(self, "#[pyclass(module = \"rlbot_flatbuffers\", frozen, hash, eq, eq_int)]");
270
+ write_str!(self, "#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]");
299
271
  write_fmt!(self, "pub enum {} {{", self.struct_name);
300
272
  write_str!(self, " #[default]");
301
273
 
@@ -309,17 +281,8 @@ impl Generator for EnumBindGenerator {
309
281
  }
310
282
 
311
283
  fn generate_from_flat_impls(&mut self) {
312
- write_fmt!(
313
- self,
314
- "impl From<flat::{}> for {} {{",
315
- self.struct_name,
316
- self.struct_name
317
- );
318
- write_fmt!(
319
- self,
320
- " fn from(flat_t: flat::{}) -> Self {{",
321
- self.struct_name
322
- );
284
+ write_fmt!(self, "impl From<flat::{}> for {} {{", self.struct_name, self.struct_name);
285
+ write_fmt!(self, " fn from(flat_t: flat::{}) -> Self {{", self.struct_name);
323
286
  write_str!(self, " match flat_t {");
324
287
 
325
288
  for variable_info in &self.types {
@@ -332,11 +295,7 @@ impl Generator for EnumBindGenerator {
332
295
  );
333
296
  }
334
297
 
335
- write_fmt!(
336
- self,
337
- " _ => Self::{},",
338
- self.types.last().unwrap().name.as_str()
339
- );
298
+ write_fmt!(self, " _ => Self::{},", self.types.last().unwrap().name.as_str());
340
299
 
341
300
  write_str!(self, " }");
342
301
  write_str!(self, " }");
@@ -345,17 +304,8 @@ impl Generator for EnumBindGenerator {
345
304
  }
346
305
 
347
306
  fn generate_to_flat_impls(&mut self) {
348
- write_fmt!(
349
- self,
350
- "impl From<&{}> for flat::{} {{",
351
- self.struct_name,
352
- self.struct_name
353
- );
354
- write_fmt!(
355
- self,
356
- " fn from(py_type: &{}) -> Self {{",
357
- self.struct_name
358
- );
307
+ write_fmt!(self, "impl From<&{}> for flat::{} {{", self.struct_name, self.struct_name);
308
+ write_fmt!(self, " fn from(py_type: &{}) -> Self {{", self.struct_name);
359
309
  write_str!(self, " match *py_type {");
360
310
 
361
311
  for variable_info in &self.types {
@@ -53,15 +53,10 @@ impl PythonBindType {
53
53
  "PredictionSlice",
54
54
  "BallPrediction",
55
55
  ];
56
- pub const UNIONS: [&'static str; 4] = [
57
- "PlayerClass",
58
- "CollisionShape",
59
- "RelativeAnchor",
60
- "RenderType",
61
- ];
56
+ pub const UNIONS: [&'static str; 4] = ["PlayerClass", "CollisionShape", "RelativeAnchor", "RenderType"];
62
57
 
63
- pub const DEFAULT_OVERRIDES: [(&'static str, &'static str, &'static str); 1] =
64
- [("Color", "a", "255")];
58
+ pub const OPTIONAL_UNIONS: [&'static str; 1] = ["RelativeAnchor"];
59
+ pub const DEFAULT_OVERRIDES: [(&'static str, &'static str, &'static str); 1] = [("Color", "a", "255")];
65
60
  pub const FREELIST_TYPES: [(&'static str, usize); 0] = [];
66
61
 
67
62
  fn new(path: &Path) -> Option<Self> {
@@ -106,12 +101,7 @@ impl PythonBindType {
106
101
  let struct_doc_str = if docs.is_empty() {
107
102
  None
108
103
  } else {
109
- Some(
110
- docs.into_iter()
111
- .map(|s| s.to_string())
112
- .rev()
113
- .collect::<Vec<_>>(),
114
- )
104
+ Some(docs.into_iter().map(|s| s.to_string()).rev().collect::<Vec<_>>())
115
105
  };
116
106
 
117
107
  if let Some(types) = StructBindGenerator::get_types(&contents, &struct_t_name) {
@@ -125,15 +115,11 @@ impl PythonBindType {
125
115
  )?));
126
116
  }
127
117
 
128
- if let Some((types, enum_type)) =
129
- enums::EnumBindGenerator::get_types(&contents, &struct_name)
130
- {
118
+ if let Some((types, enum_type)) = enums::EnumBindGenerator::get_types(&contents, &struct_name) {
131
119
  return Some(match enum_type {
132
- enums::EnumType::Enum => Self::Enum(enums::EnumBindGenerator::new(
133
- filename.to_string(),
134
- struct_name,
135
- types,
136
- )?),
120
+ enums::EnumType::Enum => {
121
+ Self::Enum(enums::EnumBindGenerator::new(filename.to_string(), struct_name, types)?)
122
+ }
137
123
  enums::EnumType::Union => Self::Union(unions::UnionBindGenerator::new(
138
124
  filename.to_string(),
139
125
  struct_name,
@@ -183,10 +169,7 @@ fn mod_rs_generator(type_data: &[PythonBindType]) -> io::Result<()> {
183
169
 
184
170
  file_contents.push(Cow::Borrowed(""));
185
171
 
186
- fs::write(
187
- format!("{PYTHON_OUT_FOLDER}/mod.rs"),
188
- file_contents.join("\n"),
189
- )?;
172
+ fs::write(format!("{PYTHON_OUT_FOLDER}/mod.rs"), file_contents.join("\n"))?;
190
173
 
191
174
  Ok(())
192
175
  }
@@ -204,10 +187,7 @@ fn run_flatc() -> io::Result<()> {
204
187
  let mut schema_folder = Path::new(SCHEMA_FOLDER);
205
188
  if !schema_folder.exists() {
206
189
  schema_folder = Path::new(SCHEMA_FOLDER_BACKUP);
207
- assert!(
208
- schema_folder.exists(),
209
- "Could not find flatbuffers schema folder"
210
- );
190
+ assert!(schema_folder.exists(), "Could not find flatbuffers schema folder");
211
191
  }
212
192
 
213
193
  let schema_folder_str = schema_folder.display();
@@ -93,16 +93,10 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
93
93
  write_str!(file, " def __new__(cls, value: int = 0): ...");
94
94
  write_str!(file, " def __init__(self, value: int = 0):");
95
95
  write_str!(file, " \"\"\"");
96
- write_str!(
97
- file,
98
- " :raises ValueError: If the `value` is not a valid enum value"
99
- );
96
+ write_str!(file, " :raises ValueError: If the `value` is not a valid enum value");
100
97
  write_str!(file, " \"\"\"");
101
98
  write_str!(file, " def __int__(self) -> int: ...");
102
- write_fmt!(
103
- file,
104
- " def __eq__(self, other: {type_name}) -> bool: ..."
105
- );
99
+ write_fmt!(file, " def __eq__(self, other: {type_name}) -> bool: ...");
106
100
  write_str!(file, " def __hash__(self) -> str: ...");
107
101
  }
108
102
  PythonBindType::Struct(bind) => {
@@ -208,32 +202,32 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
208
202
  python_types.push("str".to_string());
209
203
  write_fmt!(file, " {variable_name}: str");
210
204
  }
211
- RustType::Union(type_name) => {
212
- write_fmt!(file, " {variable_name}: {type_name}");
205
+ RustType::Union(type_name, is_optional) => {
206
+ if *is_optional {
207
+ write_fmt!(file, " {variable_name}: Optional[{type_name}]");
208
+ } else {
209
+ write_fmt!(file, " {variable_name}: {type_name}");
210
+ }
213
211
 
214
212
  // search for the union with the name `type_name` and get the types
215
213
  let union_types = type_data
216
214
  .iter()
217
215
  .find_map(|item| match item {
218
- PythonBindType::Union(bind)
219
- if bind.struct_name() == type_name =>
220
- {
221
- Some(
222
- bind.types
223
- .iter()
224
- .skip(1)
225
- .map(|v| v.name.as_str())
226
- .collect::<Vec<_>>(),
227
- )
216
+ PythonBindType::Union(bind) if bind.struct_name() == type_name => {
217
+ Some(bind.types.iter().skip(1).map(|v| v.name.as_str()).collect::<Vec<_>>())
228
218
  }
229
219
  _ => None,
230
220
  })
231
221
  .unwrap();
232
- python_types.push(union_types.join(" | "));
222
+
223
+ let python_type = union_types.join(" | ");
224
+ python_types.push(if *is_optional {
225
+ format!("Optional[{python_type}]")
226
+ } else {
227
+ python_type
228
+ });
233
229
  }
234
- RustType::Custom(type_name)
235
- | RustType::Other(type_name)
236
- | RustType::Base(type_name) => {
230
+ RustType::Custom(type_name) | RustType::Other(type_name) | RustType::Base(type_name) => {
237
231
  python_types.push(type_name.to_string());
238
232
  write_fmt!(file, " {variable_name}: {type_name}");
239
233
  }
@@ -276,10 +270,7 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
276
270
 
277
271
  if let Some((field, value)) = bind.default_override {
278
272
  if field == variable_name {
279
- write_fmt!(
280
- file,
281
- " {variable_name}: {python_type} = {value},"
282
- );
273
+ write_fmt!(file, " {variable_name}: {python_type} = {value},");
283
274
  continue;
284
275
  }
285
276
  }
@@ -290,19 +281,15 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
290
281
  "String" => Cow::Borrowed("\"\""),
291
282
  "Vec<u8>" => Cow::Borrowed("b\"\""),
292
283
  t => {
293
- if python_type.starts_with("Optional")
294
- || t.starts_with("Option<")
295
- {
284
+ if python_type.starts_with("Optional") || t.starts_with("Option<") {
296
285
  Cow::Borrowed("None")
297
286
  } else if let Some(pos) = python_type.find('|') {
298
287
  Cow::Owned(format!("{}()", &python_type[..pos - 1]))
299
288
  } else if t.starts_with("Vec<") {
300
289
  Cow::Borrowed("[]")
301
290
  } else if t.starts_with("Box<") {
302
- let inner_type = t
303
- .trim_start_matches("Box<")
304
- .trim_end_matches('>')
305
- .trim_end_matches('T');
291
+ let inner_type =
292
+ t.trim_start_matches("Box<").trim_end_matches('>').trim_end_matches('T');
306
293
  Cow::Owned(format!("{inner_type}()"))
307
294
  } else {
308
295
  Cow::Owned(format!("{}()", t.trim_end_matches('T')))
@@ -310,10 +297,7 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
310
297
  }
311
298
  };
312
299
 
313
- write_fmt!(
314
- file,
315
- " {variable_name}: {python_type} = {default_value},"
316
- );
300
+ write_fmt!(file, " {variable_name}: {python_type} = {default_value},");
317
301
  }
318
302
 
319
303
  write_str!(file, " ): ...");
@@ -23,7 +23,7 @@ pub enum RustType {
23
23
  String,
24
24
  Box(String),
25
25
  Option(InnerOptionType, String),
26
- Union(String),
26
+ Union(String, bool),
27
27
  Custom(String),
28
28
  Base(String),
29
29
  Other(String),
@@ -82,8 +82,7 @@ impl StructBindGenerator {
82
82
  let is_frozen = PythonBindType::FROZEN_TYPES.contains(&struct_name.as_str());
83
83
  let is_no_set = PythonBindType::NO_SET_TYPES.contains(&struct_name.as_str());
84
84
 
85
- let has_complex_pack =
86
- contents.contains("pub fn pack<'b, A: flatbuffers::Allocator + 'b>(");
85
+ let has_complex_pack = contents.contains("pub fn pack<'b, A: flatbuffers::Allocator + 'b>(");
87
86
 
88
87
  let mut file_contents = vec![];
89
88
 
@@ -105,26 +104,17 @@ impl StructBindGenerator {
105
104
  file_contents.push(Cow::Borrowed("use pyo3::{prelude::*, types::*};"));
106
105
  file_contents.push(Cow::Borrowed(""));
107
106
 
108
- let default_override =
109
- PythonBindType::DEFAULT_OVERRIDES
110
- .iter()
111
- .find_map(|&(name, field, value)| {
112
- if name == struct_name.as_str() {
113
- Some((field, value))
114
- } else {
115
- None
116
- }
117
- });
107
+ let default_override = PythonBindType::DEFAULT_OVERRIDES.iter().find_map(|&(name, field, value)| {
108
+ if name == struct_name.as_str() {
109
+ Some((field, value))
110
+ } else {
111
+ None
112
+ }
113
+ });
118
114
 
119
115
  let freelist_size = PythonBindType::FREELIST_TYPES
120
116
  .iter()
121
- .find_map(|&(name, size)| {
122
- if name == struct_name.as_str() {
123
- Some(size)
124
- } else {
125
- None
126
- }
127
- })
117
+ .find_map(|&(name, size)| if name == struct_name.as_str() { Some(size) } else { None })
128
118
  .unwrap_or_default();
129
119
 
130
120
  Some(Self {
@@ -148,9 +138,7 @@ impl StructBindGenerator {
148
138
  let struct_start = contents.find(&struct_start_definition)?;
149
139
 
150
140
  let struct_end_definition = "}\n";
151
- let struct_end = contents[struct_start..]
152
- .find(struct_end_definition)
153
- .unwrap();
141
+ let struct_end = contents[struct_start..].find(struct_end_definition).unwrap();
154
142
 
155
143
  let start = struct_start + struct_start_definition.len();
156
144
  let end = struct_start + struct_end - struct_end_definition.len();
@@ -187,12 +175,7 @@ impl StructBindGenerator {
187
175
  let struct_doc_str = if docs.is_empty() {
188
176
  None
189
177
  } else {
190
- Some(
191
- docs.into_iter()
192
- .map(|s| s.to_string())
193
- .rev()
194
- .collect::<Vec<_>>(),
195
- )
178
+ Some(docs.into_iter().map(|s| s.to_string()).rev().collect::<Vec<_>>())
196
179
  };
197
180
 
198
181
  Some((name, raw_type, struct_doc_str))
@@ -232,30 +215,18 @@ impl StructBindGenerator {
232
215
  let inner = raw_type.trim_start_matches("Option<").trim_end_matches('>');
233
216
 
234
217
  if inner.starts_with("Box<") {
235
- let inner_type = inner
236
- .trim_start_matches("Box<")
237
- .trim_end_matches('>')
238
- .trim_end_matches('T');
218
+ let inner_type = inner.trim_start_matches("Box<").trim_end_matches('>').trim_end_matches('T');
239
219
  (
240
220
  RustType::Option(InnerOptionType::Box, inner_type.to_string()),
241
221
  Some(inner_type),
242
222
  )
243
223
  } else if inner == "String" {
244
- (
245
- RustType::Option(InnerOptionType::String, inner.to_string()),
246
- None,
247
- )
224
+ (RustType::Option(InnerOptionType::String, inner.to_string()), None)
248
225
  } else if PythonBindType::BASE_TYPES.contains(&inner) {
249
- (
250
- RustType::Option(InnerOptionType::BaseType, inner.to_string()),
251
- None,
252
- )
226
+ (RustType::Option(InnerOptionType::BaseType, inner.to_string()), None)
253
227
  } else {
254
228
  let inner = inner.trim_end_matches('T');
255
- (
256
- RustType::Option(InnerOptionType::Custom, inner.to_string()),
257
- Some(inner),
258
- )
229
+ (RustType::Option(InnerOptionType::Custom, inner.to_string()), Some(inner))
259
230
  }
260
231
  } else if raw_type == "String" {
261
232
  (RustType::String, None)
@@ -269,7 +240,10 @@ impl StructBindGenerator {
269
240
  let inner_type = raw_type.trim_end_matches('T');
270
241
 
271
242
  if PythonBindType::UNIONS.contains(&inner_type) {
272
- (RustType::Union(inner_type.to_string()), Some(inner_type))
243
+ (
244
+ RustType::Union(inner_type.to_string(), PythonBindType::OPTIONAL_UNIONS.contains(&inner_type)),
245
+ Some(inner_type),
246
+ )
273
247
  } else {
274
248
  (RustType::Custom(inner_type.to_string()), Some(inner_type))
275
249
  }
@@ -338,7 +312,7 @@ impl StructBindGenerator {
338
312
 
339
313
  format!("{variable_name}=None")
340
314
  }
341
- RustType::Union(_)
315
+ RustType::Union(_, _)
342
316
  | RustType::Box(_)
343
317
  | RustType::Custom(_)
344
318
  | RustType::Vec(InnerVecType::U8)
@@ -367,11 +341,7 @@ impl StructBindGenerator {
367
341
  write_str!(self, " #[allow(clippy::too_many_arguments)]");
368
342
  }
369
343
 
370
- write_fmt!(
371
- self,
372
- " #[pyo3(signature = ({}))]",
373
- signature_parts.join(", ")
374
- );
344
+ write_fmt!(self, " #[pyo3(signature = ({}))]", signature_parts.join(", "));
375
345
  write_str!(self, " pub fn new(");
376
346
 
377
347
  if needs_python {
@@ -383,18 +353,12 @@ impl StructBindGenerator {
383
353
 
384
354
  let variable_type = match &variable_info.rust_type {
385
355
  RustType::Vec(InnerVecType::Custom(_)) => Cow::Borrowed("Option<Py<PyList>>"),
386
- RustType::Vec(InnerVecType::Base(inner_type)) => {
387
- Cow::Owned(format!("Vec<{}>", inner_type))
388
- }
356
+ RustType::Vec(InnerVecType::Base(inner_type)) => Cow::Owned(format!("Vec<{}>", inner_type)),
389
357
  RustType::Vec(InnerVecType::String) => Cow::Borrowed("Vec<String>"),
390
358
  RustType::Vec(InnerVecType::U8) => Cow::Borrowed("Option<Py<PyBytes>>"),
391
359
  RustType::Box(inner_type) => Cow::Owned(format!("Option<Py<super::{inner_type}>>")),
392
- RustType::Option(InnerOptionType::BaseType, inner_type) => {
393
- Cow::Owned(format!("Option<{inner_type}>"))
394
- }
395
- RustType::Option(InnerOptionType::String, _) => {
396
- Cow::Borrowed("Option<Py<PyString>>")
397
- }
360
+ RustType::Option(InnerOptionType::BaseType, inner_type) => Cow::Owned(format!("Option<{inner_type}>")),
361
+ RustType::Option(InnerOptionType::String, _) => Cow::Borrowed("Option<Py<PyString>>"),
398
362
  RustType::Option(_, inner_type) => {
399
363
  if inner_type == "Float" {
400
364
  Cow::Borrowed("Option<crate::PartFloats>")
@@ -409,12 +373,8 @@ impl StructBindGenerator {
409
373
  item => item,
410
374
  }),
411
375
  RustType::String => Cow::Borrowed("Option<Py<PyString>>"),
412
- RustType::Union(inner_type) => {
413
- Cow::Owned(format!("Option<super::{inner_type}Union>"))
414
- }
415
- RustType::Custom(inner_type) => {
416
- Cow::Owned(format!("Option<Py<super::{inner_type}>>"))
417
- }
376
+ RustType::Union(inner_type, _) => Cow::Owned(format!("Option<super::{inner_type}Union>")),
377
+ RustType::Custom(inner_type) => Cow::Owned(format!("Option<Py<super::{inner_type}>>")),
418
378
  RustType::Other(inner_type) => Cow::Owned(format!("super::{inner_type}")),
419
379
  };
420
380
 
@@ -428,18 +388,21 @@ impl StructBindGenerator {
428
388
  let variable_name = variable_info.name.as_str();
429
389
 
430
390
  if variable_info.is_special_base.is_some() {
431
- write_fmt!(
432
- self,
433
- " {variable_name}: {variable_name}.map(|x| x.into_gil(py)),"
434
- );
391
+ write_fmt!(self, " {variable_name}: {variable_name}.map(|x| x.into_gil(py)),");
435
392
  continue;
436
393
  }
437
394
 
438
395
  match &variable_info.rust_type {
439
- RustType::Union(inner_type) => {
396
+ RustType::Union(inner_type, is_optional) => {
397
+ let end = if *is_optional {
398
+ Cow::Borrowed("")
399
+ } else {
400
+ Cow::Owned(format!(".unwrap_or_else(|| super::{inner_type}::py_default(py))"))
401
+ };
402
+
440
403
  write_fmt!(
441
404
  self,
442
- " {variable_name}: {variable_name}.map(|u| Py::new(py, super::{inner_type}::new(u)).unwrap()).unwrap_or_else(|| super::{inner_type}::py_default(py)),"
405
+ " {variable_name}: {variable_name}.map(|u| Py::new(py, super::{inner_type}::new(u)).unwrap()){end},"
443
406
  );
444
407
  }
445
408
  RustType::Box(inner_type) | RustType::Custom(inner_type) => {
@@ -491,14 +454,8 @@ impl StructBindGenerator {
491
454
  RustType::Base(inner_type) => match inner_type.as_str() {
492
455
  "f32" => {
493
456
  write_str!(self, "\n #[setter]");
494
- write_fmt!(
495
- self,
496
- " pub fn {variable_name}(&mut self, py: Python, value: f64) {{",
497
- );
498
- write_fmt!(
499
- self,
500
- " self.{variable_name} = PyFloat::new(py, value).unbind();"
501
- );
457
+ write_fmt!(self, " pub fn {variable_name}(&mut self, py: Python, value: f64) {{",);
458
+ write_fmt!(self, " self.{variable_name} = PyFloat::new(py, value).unbind();");
502
459
  write_str!(self, " }");
503
460
  }
504
461
  _ => continue,
@@ -541,11 +498,7 @@ impl StructBindGenerator {
541
498
  })
542
499
  .collect::<Vec<_>>()
543
500
  .join(", ");
544
- write_fmt!(
545
- self,
546
- " \"{}({repr_signature})\",",
547
- self.struct_name
548
- );
501
+ write_fmt!(self, " \"{}({repr_signature})\",", self.struct_name);
549
502
 
550
503
  for variable_info in &self.types {
551
504
  let variable_name = variable_info.name.as_str();
@@ -582,51 +535,46 @@ impl StructBindGenerator {
582
535
  RustType::Option(inner_type, _) => {
583
536
  write_fmt!(self, " self.{variable_name}");
584
537
  write_str!(self, " .as_ref()");
538
+ write_str!(self, " .map_or_else(crate::none_str, |i| {");
585
539
 
586
540
  match inner_type {
587
541
  InnerOptionType::BaseType => {
588
- write_str!(self, " .map(|i| format!(\"{i:?}\"))");
542
+ write_str!(self, " format!(\"{i:?}\")");
589
543
  }
590
544
  InnerOptionType::String => {
591
545
  write_str!(
592
546
  self,
593
- " .map(|i| format!(\"{:?}\", i.to_str(py).unwrap().to_string()))"
547
+ " format!(\"{:?}\", i.to_str(py).unwrap().to_string())"
594
548
  );
595
549
  }
596
550
  _ => {
597
- write_str!(self, " .map(|x| x.borrow(py).__repr__(py))");
551
+ write_str!(self, " i.borrow(py).__repr__(py)");
598
552
  }
599
553
  }
600
554
 
601
- write_str!(self, " .unwrap_or_else(crate::none_str),");
555
+ write_str!(self, " }),");
602
556
  }
603
- RustType::Union(_) => {
604
- write_fmt!(
605
- self,
606
- " self.{variable_name}.borrow(py).inner_repr(py),"
607
- );
557
+ RustType::Union(_, is_optional) => {
558
+ if *is_optional {
559
+ write_fmt!(self, " self.{variable_name}");
560
+ write_str!(self, " .as_ref()");
561
+ write_str!(self, " .map_or_else(crate::none_str, |i| i.borrow(py).inner_repr(py)),");
562
+ } else {
563
+ write_fmt!(self, " self.{variable_name}.borrow(py).inner_repr(py),");
564
+ }
608
565
  }
609
566
  RustType::Box(_) | RustType::Custom(_) => {
610
- write_fmt!(
611
- self,
612
- " self.{variable_name}.borrow(py).__repr__(py),"
613
- );
567
+ write_fmt!(self, " self.{variable_name}.borrow(py).__repr__(py),");
614
568
  }
615
569
  RustType::Base(inner_type) => {
616
570
  if inner_type == "bool" {
617
- write_fmt!(
618
- self,
619
- " crate::bool_to_str(self.{variable_name}),"
620
- );
571
+ write_fmt!(self, " crate::bool_to_str(self.{variable_name}),");
621
572
  } else {
622
573
  write_fmt!(self, " self.{variable_name},");
623
574
  }
624
575
  }
625
576
  RustType::String => {
626
- write_fmt!(
627
- self,
628
- " self.{variable_name}.bind(py).to_cow().unwrap(),"
629
- );
577
+ write_fmt!(self, " self.{variable_name}.bind(py).to_cow().unwrap(),");
630
578
  }
631
579
  RustType::Other(_) => {
632
580
  write_fmt!(self, " self.{variable_name}.__repr__(),");
@@ -640,10 +588,7 @@ impl StructBindGenerator {
640
588
 
641
589
  fn generate_long_args(&mut self) {
642
590
  write_str!(self, " #[classattr]");
643
- write_str!(
644
- self,
645
- " fn __match_args__(py: Python) -> Bound<pyo3::types::PyTuple> {"
646
- );
591
+ write_str!(self, " fn __match_args__(py: Python) -> Bound<pyo3::types::PyTuple> {");
647
592
  write_str!(self, " pyo3::types::PyTuple::new(py, [");
648
593
 
649
594
  for variable_info in &self.types {
@@ -653,10 +598,7 @@ impl StructBindGenerator {
653
598
  write_str!(self, " ]).unwrap()");
654
599
  write_str!(self, " }\n");
655
600
  write_str!(self, " #[classattr]");
656
- write_str!(
657
- self,
658
- " fn __slots__(py: Python) -> Bound<pyo3::types::PyTuple> {"
659
- );
601
+ write_str!(self, " fn __slots__(py: Python) -> Bound<pyo3::types::PyTuple> {");
660
602
  write_str!(self, " Self::__match_args__(py)");
661
603
  write_str!(self, " }\n");
662
604
  }
@@ -691,10 +633,7 @@ impl StructBindGenerator {
691
633
  }
692
634
 
693
635
  fn generate_pack_method(&mut self) {
694
- write_str!(
695
- self,
696
- " fn pack<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {"
697
- );
636
+ write_str!(self, " fn pack<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {");
698
637
  write_fmt!(
699
638
  self,
700
639
  " let flat_t = flat::{}::from_gil(py, self);",
@@ -702,15 +641,9 @@ impl StructBindGenerator {
702
641
  );
703
642
 
704
643
  if self.has_complex_pack {
705
- write_str!(
706
- self,
707
- " let size = flat_t.get_size().next_power_of_two();"
708
- );
644
+ write_str!(self, " let size = flat_t.get_size().next_power_of_two();");
709
645
  write_str!(self, "");
710
- write_str!(
711
- self,
712
- " let mut builder = FlatBufferBuilder::with_capacity(size);"
713
- );
646
+ write_str!(self, " let mut builder = FlatBufferBuilder::with_capacity(size);");
714
647
  write_str!(self, " let offset = flat_t.pack(&mut builder);");
715
648
  write_str!(self, " builder.finish(offset, None);");
716
649
  write_str!(self, "");
@@ -806,17 +739,31 @@ impl StructBindGenerator {
806
739
  " self.{variable_name}.bind_borrowed(py).borrow_mut().unpack_from(py, flat_t.{variable_name});"
807
740
  )
808
741
  }
809
- RustType::Union(_) => {
742
+ RustType::Union(inner_type, true) => {
743
+ write_fmt!(self, " match flat_t.{variable_name} {{");
744
+ write_fmt!(self, " flat::{inner_type}T::NONE => self.{variable_name} = None,");
745
+ write_str!(self, " x => {");
746
+ write_fmt!(self, " match &mut self.{variable_name} {{");
747
+ write_str!(
748
+ self,
749
+ " Some(item) => item.bind_borrowed(py).borrow_mut().unpack_from(py, x),"
750
+ );
751
+ write_fmt!(
752
+ self,
753
+ " None => self.{variable_name} = Some(crate::into_py_from(py, x)),"
754
+ );
755
+ write_str!(self, " }");
756
+ write_str!(self, " }");
757
+ write_str!(self, " }");
758
+ }
759
+ RustType::Union(_, false) => {
810
760
  let conv_str = if variable_info.is_frozen {
811
761
  " = crate::into_py_from"
812
762
  } else {
813
763
  ".bind_borrowed(py).borrow_mut().unpack_from"
814
764
  };
815
765
 
816
- write_fmt!(
817
- self,
818
- " self.{variable_name}{conv_str}(py, flat_t.{variable_name});"
819
- );
766
+ write_fmt!(self, " self.{variable_name}{conv_str}(py, flat_t.{variable_name});");
820
767
  }
821
768
  RustType::String => {
822
769
  write_fmt!(
@@ -832,22 +779,13 @@ impl StructBindGenerator {
832
779
  );
833
780
  }
834
781
  _ => {
835
- write_fmt!(
836
- self,
837
- " self.{variable_name} = flat_t.{variable_name};"
838
- );
782
+ write_fmt!(self, " self.{variable_name} = flat_t.{variable_name};");
839
783
  }
840
784
  },
841
785
  RustType::Other(_) => {
842
- write_fmt!(
843
- self,
844
- " self.{variable_name} = flat_t.{variable_name}.into();",
845
- );
786
+ write_fmt!(self, " self.{variable_name} = flat_t.{variable_name}.into();",);
846
787
  }
847
- _ => write_fmt!(
848
- self,
849
- " self.{variable_name} = flat_t.{variable_name};"
850
- ),
788
+ _ => write_fmt!(self, " self.{variable_name} = flat_t.{variable_name};"),
851
789
  }
852
790
  }
853
791
 
@@ -860,16 +798,9 @@ impl StructBindGenerator {
860
798
  self,
861
799
  " fn unpack_with(&mut self, py: Python, data: &[u8]) -> PyResult<()> {{"
862
800
  );
863
- write_fmt!(
864
- self,
865
- " match root::<flat::{}>(data) {{",
866
- self.struct_name
867
- );
801
+ write_fmt!(self, " match root::<flat::{}>(data) {{", self.struct_name);
868
802
  write_str!(self, " Ok(flat_t) => {");
869
- write_str!(
870
- self,
871
- " self.unpack_from(py, flat_t.unpack());"
872
- );
803
+ write_str!(self, " self.unpack_from(py, flat_t.unpack());");
873
804
  write_str!(self, " Ok(())");
874
805
  write_str!(self, " }");
875
806
  write_str!(self, " Err(e) => Err(flat_err_to_py(e)),");
@@ -879,15 +810,8 @@ impl StructBindGenerator {
879
810
 
880
811
  fn generate_unpack_method(&mut self) {
881
812
  write_str!(self, " #[staticmethod]");
882
- write_str!(
883
- self,
884
- " fn unpack(py: Python, data: &[u8]) -> PyResult<Py<Self>> {"
885
- );
886
- write_fmt!(
887
- self,
888
- " match root::<flat::{}>(data) {{",
889
- self.struct_name
890
- );
813
+ write_str!(self, " fn unpack(py: Python, data: &[u8]) -> PyResult<Py<Self>> {");
814
+ write_fmt!(self, " match root::<flat::{}>(data) {{", self.struct_name);
891
815
  write_str!(
892
816
  self,
893
817
  " Ok(flat_t) => Ok(crate::into_py_from(py, flat_t.unpack())),"
@@ -924,15 +848,9 @@ impl Generator for StructBindGenerator {
924
848
  contents = contents.replace("\r\n", "\n");
925
849
  }
926
850
 
927
- contents = contents.replace(
928
- "use self::flatbuffers",
929
- "use get_size::GetSize;\nuse self::flatbuffers",
930
- );
851
+ contents = contents.replace("use self::flatbuffers", "use get_size::GetSize;\nuse self::flatbuffers");
931
852
 
932
- contents = contents.replace(
933
- "#[derive(Debug, Clone, PartialEq)]\n",
934
- "#[derive(PartialEq, GetSize)]\n",
935
- );
853
+ contents = contents.replace("#[derive(Debug, Clone, PartialEq)]\n", "#[derive(PartialEq, GetSize)]\n");
936
854
 
937
855
  contents = contents.replace(
938
856
  "#[derive(Debug, Clone, PartialEq, Default)]\n",
@@ -992,10 +910,10 @@ impl Generator for StructBindGenerator {
992
910
  RustType::Option(InnerOptionType::BaseType, inner_type) => {
993
911
  format!("Option<Py<{inner_type}>>")
994
912
  }
995
- RustType::Option(InnerOptionType::String, _) => {
996
- String::from("Option<Py<PyString>>")
913
+ RustType::Option(InnerOptionType::String, _) => String::from("Option<Py<PyString>>"),
914
+ RustType::Union(inner_type, true) | RustType::Option(_, inner_type) => {
915
+ format!("Option<Py<super::{inner_type}>>")
997
916
  }
998
- RustType::Option(_, inner_type) => format!("Option<Py<super::{inner_type}>>"),
999
917
  RustType::Base(inner_type) => match inner_type.as_str() {
1000
918
  "f32" => {
1001
919
  add_set = false;
@@ -1004,7 +922,7 @@ impl Generator for StructBindGenerator {
1004
922
  _ => inner_type.clone(),
1005
923
  },
1006
924
  RustType::String => String::from("Py<PyString>"),
1007
- RustType::Union(inner_type) | RustType::Custom(inner_type) => {
925
+ RustType::Union(inner_type, false) | RustType::Custom(inner_type) => {
1008
926
  format!("Py<super::{inner_type}>")
1009
927
  }
1010
928
  RustType::Other(inner_type) => format!("super::{inner_type}"),
@@ -1036,14 +954,10 @@ impl Generator for StructBindGenerator {
1036
954
 
1037
955
  let end = match &variable_info.rust_type {
1038
956
  RustType::Vec(InnerVecType::U8) => Cow::Borrowed("PyBytes::new(py, &[]).unbind()"),
1039
- RustType::Vec(InnerVecType::Custom(_)) => {
1040
- Cow::Borrowed("PyList::empty(py).unbind()")
1041
- }
957
+ RustType::Vec(InnerVecType::Custom(_)) => Cow::Borrowed("PyList::empty(py).unbind()"),
1042
958
  RustType::Vec(_) => Cow::Borrowed("Vec::new()"),
1043
- RustType::Option(_, _) => Cow::Borrowed("None"),
1044
- RustType::Union(inner_type)
1045
- | RustType::Box(inner_type)
1046
- | RustType::Custom(inner_type) => {
959
+ RustType::Union(_, true) | RustType::Option(_, _) => Cow::Borrowed("None"),
960
+ RustType::Union(inner_type, false) | RustType::Box(inner_type) | RustType::Custom(inner_type) => {
1047
961
  Cow::Owned(format!("super::{inner_type}::py_default(py)"))
1048
962
  }
1049
963
  RustType::Base(inner_type) => Cow::Borrowed(match inner_type.as_str() {
@@ -1081,17 +995,10 @@ impl Generator for StructBindGenerator {
1081
995
  return;
1082
996
  }
1083
997
 
1084
- write_fmt!(
1085
- self,
1086
- "impl FromGil<{impl_type}> for {} {{",
1087
- self.struct_name
1088
- );
998
+ write_fmt!(self, "impl FromGil<{impl_type}> for {} {{", self.struct_name);
1089
999
 
1090
1000
  write_str!(self, " #[allow(unused_variables)]");
1091
- write_fmt!(
1092
- self,
1093
- " fn from_gil(py: Python, flat_t: {impl_type}) -> Self {{"
1094
- );
1001
+ write_fmt!(self, " fn from_gil(py: Python, flat_t: {impl_type}) -> Self {{");
1095
1002
  write_fmt!(self, " {} {{", self.struct_name);
1096
1003
 
1097
1004
  for variable_info in &self.types {
@@ -1137,7 +1044,13 @@ impl Generator for StructBindGenerator {
1137
1044
  " {variable_name}: crate::into_py_from(py, *flat_t.{variable_name}),",
1138
1045
  );
1139
1046
  }
1140
- RustType::Union(_) | RustType::Custom(_) => {
1047
+ RustType::Union(inner_type, true) => {
1048
+ write_fmt!(self, " {variable_name}: match flat_t.{variable_name} {{");
1049
+ write_fmt!(self, " flat::{inner_type}T::NONE => None,");
1050
+ write_str!(self, " x => Some(crate::into_py_from(py, x)),");
1051
+ write_str!(self, " },");
1052
+ }
1053
+ RustType::Union(_, false) | RustType::Custom(_) => {
1141
1054
  write_fmt!(
1142
1055
  self,
1143
1056
  " {variable_name}: crate::into_py_from(py, flat_t.{variable_name}),",
@@ -1161,10 +1074,7 @@ impl Generator for StructBindGenerator {
1161
1074
  }
1162
1075
  },
1163
1076
  RustType::Other(_) => {
1164
- write_fmt!(
1165
- self,
1166
- " {variable_name}: flat_t.{variable_name}.into(),",
1167
- );
1077
+ write_fmt!(self, " {variable_name}: flat_t.{variable_name}.into(),",);
1168
1078
  }
1169
1079
  }
1170
1080
  }
@@ -1188,18 +1098,10 @@ impl Generator for StructBindGenerator {
1188
1098
  return;
1189
1099
  }
1190
1100
 
1191
- write_fmt!(
1192
- self,
1193
- "impl FromGil<&{}> for {impl_type} {{",
1194
- self.struct_name
1195
- );
1101
+ write_fmt!(self, "impl FromGil<&{}> for {impl_type} {{", self.struct_name);
1196
1102
 
1197
1103
  write_str!(self, " #[allow(unused_variables)]");
1198
- write_fmt!(
1199
- self,
1200
- " fn from_gil(py: Python, py_type: &{}) -> Self {{",
1201
- self.struct_name
1202
- );
1104
+ write_fmt!(self, " fn from_gil(py: Python, py_type: &{}) -> Self {{", self.struct_name);
1203
1105
  write_str!(self, " Self {");
1204
1106
 
1205
1107
  for variable_info in &self.types {
@@ -1213,10 +1115,7 @@ impl Generator for StructBindGenerator {
1213
1115
  )
1214
1116
  }
1215
1117
  RustType::Vec(InnerVecType::String | InnerVecType::Base(_)) => {
1216
- write_fmt!(
1217
- self,
1218
- " {variable_name}: py_type.{variable_name}.clone(),"
1219
- )
1118
+ write_fmt!(self, " {variable_name}: py_type.{variable_name}.clone(),")
1220
1119
  }
1221
1120
  RustType::Vec(InnerVecType::Custom(_)) => {
1222
1121
  write_fmt!(
@@ -1248,7 +1147,18 @@ impl Generator for StructBindGenerator {
1248
1147
  " {variable_name}: Box::new(crate::from_py_into(py, &py_type.{variable_name})),",
1249
1148
  );
1250
1149
  }
1251
- RustType::Union(_) | RustType::Custom(_) => {
1150
+ RustType::Union(inner_type, true) => {
1151
+ write_fmt!(self, " {variable_name}: py_type");
1152
+ write_fmt!(self, " .{variable_name}");
1153
+ write_str!(self, " .as_ref()");
1154
+ write_fmt!(self, " .map_or(flat::{inner_type}T::NONE, |x| {{");
1155
+ write_fmt!(
1156
+ self,
1157
+ " crate::from_py_into::<_, flat::{inner_type}T>(py, x).into()"
1158
+ );
1159
+ write_str!(self, " }),");
1160
+ }
1161
+ RustType::Union(_, false) | RustType::Custom(_) => {
1252
1162
  write_fmt!(
1253
1163
  self,
1254
1164
  " {variable_name}: crate::from_py_into(py, &py_type.{variable_name}),",
@@ -1268,17 +1178,11 @@ impl Generator for StructBindGenerator {
1268
1178
  );
1269
1179
  }
1270
1180
  _ => {
1271
- write_fmt!(
1272
- self,
1273
- " {variable_name}: py_type.{variable_name},"
1274
- );
1181
+ write_fmt!(self, " {variable_name}: py_type.{variable_name},");
1275
1182
  }
1276
1183
  },
1277
1184
  RustType::Other(_) => {
1278
- write_fmt!(
1279
- self,
1280
- " {variable_name}: (&py_type.{variable_name}).into(),",
1281
- );
1185
+ write_fmt!(self, " {variable_name}: (&py_type.{variable_name}).into(),",);
1282
1186
  }
1283
1187
  }
1284
1188
  }
@@ -24,12 +24,7 @@ macro_rules! write_fmt {
24
24
  }
25
25
 
26
26
  impl UnionBindGenerator {
27
- pub fn new(
28
- filename: String,
29
- struct_name: String,
30
- struct_t_name: String,
31
- types: Vec<CustomEnumType>,
32
- ) -> Option<Self> {
27
+ pub fn new(filename: String, struct_name: String, struct_t_name: String, types: Vec<CustomEnumType>) -> Option<Self> {
33
28
  let is_frozen = PythonBindType::FROZEN_TYPES.contains(&struct_name.as_str());
34
29
  let is_no_set = PythonBindType::NO_SET_TYPES.contains(&struct_name.as_str());
35
30
 
@@ -54,20 +49,13 @@ impl UnionBindGenerator {
54
49
  assert!(u8::try_from(self.types.len()).is_ok());
55
50
 
56
51
  write_str!(self, " #[new]");
57
- write_fmt!(
58
- self,
59
- " pub fn new(item: {}Union) -> Self {{",
60
- self.struct_name
61
- );
52
+ write_fmt!(self, " pub fn new(item: {}Union) -> Self {{", self.struct_name);
62
53
  write_str!(self, " Self { item }");
63
54
  write_str!(self, " }");
64
55
  write_str!(self, "");
65
56
  write_str!(self, " #[getter(item)]");
66
57
 
67
- write_str!(
68
- self,
69
- " pub fn get(&self, py: Python) -> Option<Py<PyAny>> {"
70
- );
58
+ write_str!(self, " pub fn get(&self, py: Python) -> Option<Py<PyAny>> {");
71
59
  write_str!(self, " match &self.item {");
72
60
 
73
61
  for variable_info in &self.types {
@@ -152,11 +140,7 @@ impl UnionBindGenerator {
152
140
  let variable_name = variable_info.name.as_str();
153
141
 
154
142
  if variable_name == "NONE" {
155
- write_fmt!(
156
- self,
157
- " flat::{}::NONE => unreachable!(),",
158
- self.struct_t_name
159
- );
143
+ write_fmt!(self, " flat::{}::NONE => unreachable!(),", self.struct_t_name);
160
144
  continue;
161
145
  }
162
146
 
@@ -216,15 +200,9 @@ impl Generator for UnionBindGenerator {
216
200
  contents = contents.replace("\r\n", "\n");
217
201
  }
218
202
 
219
- contents = contents.replace(
220
- "use self::flatbuffers",
221
- "use get_size::GetSize;\nuse self::flatbuffers",
222
- );
203
+ contents = contents.replace("use self::flatbuffers", "use get_size::GetSize;\nuse self::flatbuffers");
223
204
 
224
- contents = contents.replace(
225
- "#[derive(Debug, Clone, PartialEq)]\n",
226
- "#[derive(PartialEq, GetSize)]\n",
227
- );
205
+ contents = contents.replace("#[derive(Debug, Clone, PartialEq)]\n", "#[derive(PartialEq, GetSize)]\n");
228
206
 
229
207
  // delete unneeded auto-generated source code from flatc
230
208
  let start = contents.find("impl core::fmt::Debug for ").unwrap();
@@ -291,12 +269,7 @@ impl Generator for UnionBindGenerator {
291
269
  }
292
270
 
293
271
  fn generate_from_flat_impls(&mut self) {
294
- write_fmt!(
295
- self,
296
- "impl FromGil<flat::{}> for {} {{",
297
- self.struct_t_name,
298
- self.struct_name
299
- );
272
+ write_fmt!(self, "impl FromGil<flat::{}> for {} {{", self.struct_t_name, self.struct_name);
300
273
  write_fmt!(
301
274
  self,
302
275
  " fn from_gil(py: Python, flat_t: flat::{}) -> Self {{",
@@ -309,11 +282,7 @@ impl Generator for UnionBindGenerator {
309
282
  let variable_name = variable_info.name.as_str();
310
283
 
311
284
  if variable_name == "NONE" {
312
- write_fmt!(
313
- self,
314
- " flat::{}::NONE => unreachable!(),",
315
- self.struct_t_name,
316
- );
285
+ write_fmt!(self, " flat::{}::NONE => unreachable!(),", self.struct_t_name,);
317
286
  } else {
318
287
  write_fmt!(
319
288
  self,
@@ -322,11 +291,7 @@ impl Generator for UnionBindGenerator {
322
291
  self.struct_name,
323
292
  );
324
293
 
325
- write_fmt!(
326
- self,
327
- " item: {}Union::{variable_name}(",
328
- self.struct_name
329
- );
294
+ write_fmt!(self, " item: {}Union::{variable_name}(", self.struct_name);
330
295
 
331
296
  write_fmt!(
332
297
  self,
@@ -351,11 +316,7 @@ impl Generator for UnionBindGenerator {
351
316
  self.struct_name,
352
317
  self.struct_t_name
353
318
  );
354
- write_fmt!(
355
- self,
356
- " fn from_gil(py: Python, py_type: &{}) -> Self {{",
357
- self.struct_name
358
- );
319
+ write_fmt!(self, " fn from_gil(py: Python, py_type: &{}) -> Self {{", self.struct_name);
359
320
 
360
321
  write_str!(self, " match &py_type.item {");
361
322
 
@@ -363,11 +324,7 @@ impl Generator for UnionBindGenerator {
363
324
  let variable_name = variable_info.name.as_str();
364
325
 
365
326
  if let Some(ref value) = variable_info.value {
366
- write_fmt!(
367
- self,
368
- " {}Union::{value}(item) => {{",
369
- self.struct_name,
370
- );
327
+ write_fmt!(self, " {}Union::{value}(item) => {{", self.struct_name,);
371
328
 
372
329
  write_fmt!(
373
330
  self,
@@ -15,19 +15,11 @@ pub mod generated;
15
15
  #[allow(clippy::enum_variant_names, clippy::useless_conversion, unused_imports)]
16
16
  mod python;
17
17
 
18
- use pyo3::{
19
- PyClass, create_exception, exceptions::PyValueError, prelude::*,
20
- pyclass::boolean_struct::False, types::*,
21
- };
18
+ use pyo3::{PyClass, create_exception, exceptions::PyValueError, prelude::*, pyclass::boolean_struct::False, types::*};
22
19
  use python::*;
23
20
  use std::{panic::Location, path::MAIN_SEPARATOR};
24
21
 
25
- create_exception!(
26
- rlbot_flatbuffers,
27
- InvalidFlatbuffer,
28
- PyValueError,
29
- "Invalid FlatBuffer"
30
- );
22
+ create_exception!(rlbot_flatbuffers, InvalidFlatbuffer, PyValueError, "Invalid FlatBuffer");
31
23
 
32
24
  #[inline(never)]
33
25
  #[track_caller]
@@ -147,11 +139,7 @@ where
147
139
 
148
140
  for py_item in items.iter() {
149
141
  match script_iter.next() {
150
- Some(item) => py_item
151
- .downcast_into_exact::<U>()
152
- .unwrap()
153
- .borrow_mut()
154
- .unpack_from(py, item),
142
+ Some(item) => py_item.downcast_into_exact::<U>().unwrap().borrow_mut().unpack_from(py, item),
155
143
  None => {
156
144
  let items_len = items.len();
157
145
  for i in 0..items_len - scripts_len {