Skip to content

Commit 9c14d33

Browse files
committed
Unions can no longer be None
1 parent ae278a5 commit 9c14d33

File tree

3 files changed

+39
-43
lines changed

3 files changed

+39
-43
lines changed

codegen/pyi.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
5656
.map(|variable_info| variable_info.name.as_str())
5757
.filter(|variable_name| *variable_name != "NONE")
5858
.collect::<Vec<_>>();
59+
let default_value = types.first().unwrap();
5960
let union_str = types.join(" | ");
6061

61-
write_fmt!(file, " item: Optional[{union_str}]");
62+
write_fmt!(file, " item: {union_str}");
6263
write_str!(file, "");
6364
write_str!(file, " def __new__(");
64-
write_fmt!(file, " cls, item: Optional[{union_str}] = None");
65+
write_fmt!(file, " cls, item: {union_str} = {default_value}()");
6566
write_str!(file, " ): ...");
6667
write_str!(file, " def __init__(");
67-
write_fmt!(file, " self, item: Optional[{union_str}] = None");
68+
write_fmt!(file, " self, item: {union_str} = {default_value}()");
6869
write_str!(file, " ): ...\n");
6970
}
7071
PythonBindType::Enum(gen) => {
@@ -228,8 +229,7 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
228229
_ => None,
229230
})
230231
.unwrap();
231-
let types = union_types.join(" | ");
232-
python_types.push(format!("Optional[{types}]"));
232+
python_types.push(union_types.join(" | "));
233233
}
234234
RustType::Custom(type_name)
235235
| RustType::Other(type_name)
@@ -284,6 +284,8 @@ pub fn generator(type_data: &[PythonBindType]) -> io::Result<()> {
284284
|| t.starts_with("Option<")
285285
{
286286
Cow::Borrowed("None")
287+
} else if let Some(pos) = python_type.find('|') {
288+
Cow::Owned(format!("{}()", &python_type[..pos - 1]))
287289
} else if t.starts_with("Vec<") {
288290
Cow::Borrowed("[]")
289291
} else if t.starts_with("Box<") {

codegen/structs.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,11 @@ impl StructBindGenerator {
404404
RustType::Union(inner_type) => {
405405
write_fmt!(
406406
self,
407-
" {variable_name}: Py::new(py, super::{}::new({variable_name})).unwrap(),",
408-
inner_type
407+
" {variable_name}: {variable_name}.map(|u| Py::new(py, super::{inner_type}::new(u)).unwrap()).unwrap_or_else(|| super::{inner_type}::py_default(py)),"
409408
);
410409
}
411410
RustType::Box(inner_type) | RustType::Custom(inner_type) => {
412-
write_fmt!(self, " {variable_name}: {variable_name}.unwrap_or_else(|| super::{inner_type}::py_default(py)),",);
411+
write_fmt!(self, " {variable_name}: {variable_name}.unwrap_or_else(|| super::{inner_type}::py_default(py)),");
413412
}
414413
RustType::Vec(InnerVecType::U8) => {
415414
write_fmt!(

codegen/unions.rs

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ impl UnionBindGenerator {
5151
assert!(u8::try_from(self.types.len()).is_ok());
5252

5353
write_str!(self, " #[new]");
54-
write_str!(self, " #[pyo3(signature = (item = None))]");
5554
write_fmt!(
5655
self,
57-
" pub fn new(item: Option<{}Union>) -> Self {{",
56+
" pub fn new(item: {}Union) -> Self {{",
5857
self.struct_name
5958
);
6059
write_str!(self, " Self { item }");
@@ -66,17 +65,15 @@ impl UnionBindGenerator {
6665
self,
6766
" pub fn get(&self, py: Python) -> Option<Py<PyAny>> {"
6867
);
69-
write_str!(self, " match self.item.as_ref() {");
68+
write_str!(self, " match &self.item {");
7069

7170
for variable_info in &self.types {
7271
let variable_name = variable_info.name.as_str();
7372

74-
if variable_name == "NONE" {
75-
write_str!(self, " None => None,");
76-
} else {
73+
if variable_name != "NONE" {
7774
write_fmt!(
7875
self,
79-
" Some({}Union::{variable_name}(item)) => Some(item.clone_ref(py).into_any()),",
76+
" {}Union::{variable_name}(item) => Some(item.clone_ref(py).into_any()),",
8077
self.struct_name
8178
);
8279
}
@@ -94,19 +91,17 @@ impl UnionBindGenerator {
9491

9592
fn generate_inner_repr_method(&mut self) {
9693
write_str!(self, " pub fn inner_repr(&self, py: Python) -> String {");
97-
write_str!(self, " match self.item.as_ref() {");
94+
write_str!(self, " match &self.item {");
9895

9996
for variable_info in &self.types {
10097
let variable_name = variable_info.name.as_str();
10198

10299
if variable_info.value.is_some() {
103100
write_fmt!(
104101
self,
105-
" Some({}Union::{variable_name}(item)) => item.borrow(py).__repr__(py),",
102+
" {}Union::{variable_name}(item) => item.borrow(py).__repr__(py),",
106103
self.struct_name
107104
);
108-
} else {
109-
write_str!(self, " None => crate::none_str(),");
110105
}
111106
}
112107

@@ -116,24 +111,18 @@ impl UnionBindGenerator {
116111

117112
fn generate_repr_method(&mut self) {
118113
write_str!(self, " pub fn __repr__(&self, py: Python) -> String {");
119-
write_str!(self, " match self.item.as_ref() {");
114+
write_str!(self, " match &self.item {");
120115

121116
for variable_info in &self.types {
122117
let variable_name = variable_info.name.as_str();
123118

124119
if variable_info.value.is_some() {
125120
write_fmt!(
126121
self,
127-
" Some({}Union::{variable_name}(item)) => format!(\"{}({{}})\", item.borrow(py).__repr__(py)),",
122+
" {}Union::{variable_name}(item) => format!(\"{}({{}})\", item.borrow(py).__repr__(py)),",
128123
self.struct_name,
129124
self.struct_name
130125
);
131-
} else {
132-
write_fmt!(
133-
self,
134-
" None => String::from(\"{}()\"),",
135-
self.struct_name
136-
);
137126
}
138127
}
139128

@@ -177,7 +166,7 @@ impl Generator for UnionBindGenerator {
177166
}
178167

179168
fn generate_definition(&mut self) {
180-
write_fmt!(self, "#[derive(Debug, pyo3::FromPyObject)]");
169+
write_fmt!(self, "#[derive(pyo3::FromPyObject)]");
181170
write_fmt!(self, "pub enum {}Union {{", self.struct_name);
182171

183172
for variable_info in self.types.iter().skip(1) {
@@ -192,17 +181,26 @@ impl Generator for UnionBindGenerator {
192181
if self.is_frozen {
193182
write_str!(self, "#[pyclass(module = \"rlbot_flatbuffers\", frozen)]");
194183
} else {
195-
write_str!(self, "#[pyclass(module = \"rlbot_flatbuffers\")]");
184+
write_str!(self, "#[pyclass(module = \"rlbot_flatbuffers\", set_all)]");
196185
}
197186

198-
write_fmt!(self, "#[derive(Debug, Default)]");
199187
write_fmt!(self, "pub struct {} {{", self.struct_name);
188+
write_fmt!(self, " item: {}Union,", self.struct_name);
189+
write_str!(self, "}");
190+
write_str!(self, "");
200191

201-
if !self.is_frozen {
202-
write_str!(self, " #[pyo3(set)]");
203-
}
204-
205-
write_fmt!(self, " pub item: Option<{}Union>,", self.struct_name);
192+
write_fmt!(self, "impl crate::PyDefault for {} {{", self.struct_name);
193+
write_str!(self, " fn py_default(py: Python) -> Py<Self> {");
194+
write_str!(self, " Py::new(py, Self {");
195+
write_fmt!(
196+
self,
197+
" item: {}Union::{}(super::{}::py_default(py)),",
198+
self.struct_name,
199+
self.types[1].name,
200+
self.types[1].name
201+
);
202+
write_str!(self, " }).unwrap()");
203+
write_str!(self, " }");
206204
write_str!(self, "}");
207205
write_str!(self, "");
208206
}
@@ -228,9 +226,8 @@ impl Generator for UnionBindGenerator {
228226
if variable_name == "NONE" {
229227
write_fmt!(
230228
self,
231-
" flat::{}::NONE => {}::default(),",
229+
" flat::{}::NONE => unreachable!(),",
232230
self.struct_t_name,
233-
self.struct_name
234231
);
235232
} else {
236233
write_fmt!(
@@ -242,7 +239,7 @@ impl Generator for UnionBindGenerator {
242239

243240
write_fmt!(
244241
self,
245-
" item: Some({}Union::{variable_name}(",
242+
" item: {}Union::{variable_name}(",
246243
self.struct_name
247244
);
248245

@@ -251,7 +248,7 @@ impl Generator for UnionBindGenerator {
251248
" Py::new(py, super::{variable_name}::from_gil(py, *item)).unwrap(),"
252249
);
253250

254-
write_fmt!(self, " )),");
251+
write_fmt!(self, " ),");
255252
write_fmt!(self, " }},");
256253
}
257254
}
@@ -275,15 +272,15 @@ impl Generator for UnionBindGenerator {
275272
self.struct_name
276273
);
277274

278-
write_str!(self, " match py_type.item.as_ref() {");
275+
write_str!(self, " match &py_type.item {");
279276

280277
for variable_info in &self.types {
281278
let variable_name = variable_info.name.as_str();
282279

283280
if let Some(ref value) = variable_info.value {
284281
write_fmt!(
285282
self,
286-
" Some({}Union::{value}(item)) => {{",
283+
" {}Union::{value}(item) => {{",
287284
self.struct_name,
288285
);
289286

@@ -294,8 +291,6 @@ impl Generator for UnionBindGenerator {
294291
);
295292

296293
write_str!(self, " },");
297-
} else {
298-
write_str!(self, " None => Self::NONE,");
299294
}
300295
}
301296

0 commit comments

Comments
 (0)