Skip to content

Commit 2694076

Browse files
committed
Flatten unions in struct constructors
1 parent 8ee787e commit 2694076

11 files changed

Lines changed: 225 additions & 57 deletions

File tree

Cargo.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rlbot-flatbuffers-py"
3-
version = "0.3.9"
3+
version = "0.4.0"
44
edition = "2021"
55
description = "A Python module implemented in Rust for serializing and deserializing RLBot's flatbuffers"
66
repository = "https://github.com/VirxEC/rlbot_flatbuffers_py"

codegen/enums.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ fn camel_to_snake_case(variable_name: &str) -> String {
1515
for c in variable_name.chars() {
1616
if c.is_uppercase() {
1717
if last_was_uppercase {
18-
snake_case_parts.last_mut().unwrap().push(c.to_lowercase().next().unwrap());
18+
snake_case_parts
19+
.last_mut()
20+
.unwrap()
21+
.push(c.to_lowercase().next().unwrap());
1922
} else {
2023
snake_case_parts.push(c.to_lowercase().to_string());
2124
}
@@ -170,7 +173,11 @@ impl EnumBindGenerator {
170173

171174
for variable_info in &self.types {
172175
let variable_name = variable_info.name.as_str();
173-
write_fmt!(self, " {} => Ok(Self::{variable_name}),", variable_info.raw_type);
176+
write_fmt!(
177+
self,
178+
" {} => Ok(Self::{variable_name}),",
179+
variable_info.raw_type
180+
);
174181
}
175182

176183
if self.types.len() != usize::from(u8::MAX) {
@@ -192,7 +199,11 @@ impl EnumBindGenerator {
192199

193200
fn generate_repr_method(&mut self) {
194201
write_str!(self, " pub fn __repr__(&self) -> String {");
195-
write_fmt!(self, " format!(\"{}(value={{}})\", *self as u8)", self.struct_name);
202+
write_fmt!(
203+
self,
204+
" format!(\"{}(value={{}})\", *self as u8)",
205+
self.struct_name
206+
);
196207
write_str!(self, " }");
197208
}
198209

@@ -251,7 +262,12 @@ impl Generator for EnumBindGenerator {
251262
}
252263

253264
fn generate_from_flat_impls(&mut self) {
254-
write_fmt!(self, "impl From<flat::{}> for {} {{", self.struct_name, self.struct_name);
265+
write_fmt!(
266+
self,
267+
"impl From<flat::{}> for {} {{",
268+
self.struct_name,
269+
self.struct_name
270+
);
255271
write_fmt!(self, " fn from(flat_t: flat::{}) -> Self {{", self.struct_name);
256272
write_str!(self, " match flat_t {");
257273

@@ -274,7 +290,12 @@ impl Generator for EnumBindGenerator {
274290
}
275291

276292
fn generate_to_flat_impls(&mut self) {
277-
write_fmt!(self, "impl From<&{}> for flat::{} {{", self.struct_name, self.struct_name);
293+
write_fmt!(
294+
self,
295+
"impl From<&{}> for flat::{} {{",
296+
self.struct_name,
297+
self.struct_name
298+
);
278299
write_fmt!(self, " fn from(py_type: &{}) -> Self {{", self.struct_name);
279300
write_str!(self, " match *py_type {");
280301

codegen/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ impl PythonBindType {
5858
"GameMessageWrapper",
5959
"GameMessage",
6060
];
61+
pub const UNIONS: [&'static str; 5] = [
62+
"PlayerClass",
63+
"GameMessage",
64+
"CollisionShape",
65+
"RelativeAnchor",
66+
"RenderType",
67+
];
6168

6269
fn new(path: &Path) -> Option<Self> {
6370
// get the filename without the extension

codegen/pyi.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
generator::Generator,
23
structs::{InnerOptionType, InnerVecType, RustType},
34
PythonBindType,
45
};
@@ -76,10 +77,16 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
7677
write_str!(file, "");
7778
write_str!(file, " def __init__(self, value: int = 0):");
7879
write_str!(file, " \"\"\"");
79-
write_str!(file, " :raises ValueError: If the `value` is not a valid enum value");
80+
write_str!(
81+
file,
82+
" :raises ValueError: If the `value` is not a valid enum value"
83+
);
8084
write_str!(file, " \"\"\"\n");
8185
write_str!(file, " def __int__(self) -> int: ...");
82-
write_fmt!(file, " def __richcmp__(self, other: {type_name}, op: int) -> bool: ...");
86+
write_fmt!(
87+
file,
88+
" def __richcmp__(self, other: {type_name}, op: int) -> bool: ..."
89+
);
8390
}
8491
PythonBindType::Struct(gen) => {
8592
let mut python_types = Vec::new();
@@ -134,7 +141,7 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
134141
} else {
135142
type_name.as_str()
136143
};
137-
144+
138145
python_types.push(format!("Optional[{python_type}]"));
139146
}
140147
RustType::Box(inner_type) => {
@@ -145,6 +152,22 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
145152
python_types.push("str".to_string());
146153
write_fmt!(file, " {variable_name}: str");
147154
}
155+
RustType::Union(type_name) => {
156+
write_fmt!(file, " {variable_name}: {type_name}");
157+
158+
// search for the union with the name `type_name` and get the types
159+
let union_types = type_data
160+
.iter()
161+
.find_map(|item| match item {
162+
PythonBindType::Union(gen) if gen.struct_name() == type_name => {
163+
Some(gen.types.iter().skip(1).map(|v| v.name.as_str()).collect::<Vec<_>>())
164+
}
165+
_ => None,
166+
})
167+
.unwrap();
168+
let types = union_types.join(" | ");
169+
python_types.push(format!("Optional[{types}]"));
170+
}
148171
RustType::Custom(type_name) | RustType::Other(type_name) | RustType::Base(type_name) => {
149172
python_types.push(type_name.to_string());
150173
write_fmt!(file, " {variable_name}: {type_name}");
@@ -168,14 +191,14 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
168191
"String" => Cow::Borrowed("\"\""),
169192
"Vec<u8>" => Cow::Borrowed("b\"\""),
170193
t => {
171-
if t.starts_with("Vec<") {
194+
if python_type.starts_with("Optional") || t.starts_with("Option<") {
195+
Cow::Borrowed("None")
196+
} else if t.starts_with("Vec<") {
172197
Cow::Borrowed("[]")
173198
} else if t.starts_with("Box<") {
174199
let inner_type =
175200
t.trim_start_matches("Box<").trim_end_matches('>').trim_end_matches('T');
176201
Cow::Owned(format!("{inner_type}()"))
177-
} else if t.starts_with("Option<") {
178-
Cow::Borrowed("None")
179202
} else {
180203
Cow::Owned(format!("{}()", t.trim_end_matches('T')))
181204
}

0 commit comments

Comments
 (0)