@@ -294,6 +294,8 @@ impl PythonBindGenerator {
294294 self . write_str ( "}" ) ;
295295 self . write_str ( "" ) ;
296296
297+ self . generate_union_py_methods ( ) ;
298+
297299 self . write_str ( "#[pyclass(module = \" rlbot_flatbuffers\" , get_all, set_all)]" ) ;
298300 self . write_str ( "#[derive(Debug, Default, Clone, GetSize)]" ) ;
299301 self . write_string ( format ! ( "pub struct {} {{" , self . struct_name) ) ;
@@ -319,6 +321,38 @@ impl PythonBindGenerator {
319321 self . write_str ( "" ) ;
320322 }
321323
324+ fn generate_union_py_methods ( & mut self ) {
325+ self . write_str ( "#[pymethods]" ) ;
326+ self . write_string ( format ! ( "impl {}Type {{" , self . struct_name) ) ;
327+
328+ self . write_str ( " #[new]" ) ;
329+ assert ! ( u8 :: try_from( self . types. len( ) ) . is_ok( ) ) ;
330+
331+ self . write_str ( " #[pyo3(signature = (value=Default::default()))]" ) ;
332+ self . write_str ( " pub fn new(value: u8) -> Self {" ) ;
333+ self . write_str ( " match value {" ) ;
334+
335+ for ( i, variable_info) in self . types . iter ( ) . enumerate ( ) {
336+ let variable_name = & variable_info[ 0 ] ;
337+
338+ self . file_contents
339+ . push ( Cow :: Owned ( format ! ( " {i} => Self::{variable_name}," , ) ) ) ;
340+ }
341+
342+ if self . types . len ( ) != usize:: from ( u8:: MAX ) {
343+ self . write_str ( " v => panic!(\" Unknown value: {v}\" )," ) ;
344+ }
345+
346+ self . write_str ( " }" ) ;
347+ self . write_str ( " }" ) ;
348+
349+ self . write_str ( "" ) ;
350+
351+ self . generate_str_method ( ) ;
352+
353+ self . write_str ( "}" ) ;
354+ }
355+
322356 fn generate_from_flat_impls ( & mut self ) {
323357 match self . bind_type {
324358 PythonBindType :: Enum => self . generate_enum_from_flat_impls ( ) ,
@@ -914,8 +948,11 @@ impl PythonBindGenerator {
914948 self . generate_new_method ( ) ;
915949 self . write_str ( "" ) ;
916950 self . generate_str_method ( ) ;
917- self . write_str ( "" ) ;
918- self . generate_repr_method ( ) ;
951+
952+ if self . bind_type != PythonBindType :: Enum {
953+ self . write_str ( "" ) ;
954+ self . generate_repr_method ( ) ;
955+ }
919956
920957 if self . bind_type != PythonBindType :: Union {
921958 self . write_str ( "" ) ;
@@ -997,7 +1034,6 @@ fn pyi_generator(type_data: &[(String, String, Vec<Vec<String>>)]) -> io::Result
9971034 let mut file_contents = vec ! [
9981035 Cow :: Borrowed ( "from __future__ import annotations" ) ,
9991036 Cow :: Borrowed ( "" ) ,
1000- Cow :: Borrowed ( "from enum import Enum" ) ,
10011037 Cow :: Borrowed ( "from typing import Optional" ) ,
10021038 Cow :: Borrowed ( "" ) ,
10031039 Cow :: Borrowed ( "__doc__: str" ) ,
@@ -1023,14 +1059,24 @@ fn pyi_generator(type_data: &[(String, String, Vec<Vec<String>>)]) -> io::Result
10231059 let is_union = !types. is_empty ( ) && types[ 0 ] [ 1 ] . is_empty ( ) ;
10241060
10251061 if is_union {
1026- file_contents. push ( Cow :: Owned ( format ! ( "class {type_name}Type(Enum) :" ) ) ) ;
1062+ file_contents. push ( Cow :: Owned ( format ! ( "class {type_name}Type:" ) ) ) ;
10271063
10281064 for ( i, variable_info) in types. iter ( ) . enumerate ( ) {
10291065 let variable_name = variable_info[ 0 ] . as_str ( ) ;
1030- file_contents. push ( Cow :: Owned ( format ! ( " {variable_name} = {i} " , ) ) ) ;
1066+ file_contents. push ( Cow :: Owned ( format ! ( " {variable_name} = {type_name}Type({i}) " , ) ) ) ;
10311067 }
10321068
10331069 file_contents. push ( Cow :: Borrowed ( "" ) ) ;
1070+
1071+ file_contents. push ( Cow :: Borrowed ( " def __init__(self, value: int = 0): ..." ) ) ;
1072+ file_contents. push ( Cow :: Borrowed ( " def __str__(self) -> str: ..." ) ) ;
1073+ file_contents. push ( Cow :: Borrowed ( " def __repr__(self) -> str: ..." ) ) ;
1074+ file_contents. push ( Cow :: Borrowed ( " def __int__(self) -> int: ..." ) ) ;
1075+ file_contents. push ( Cow :: Owned ( format ! (
1076+ " def __richcmp__(self, other: {type_name}, op: int) -> bool: ..."
1077+ ) ) ) ;
1078+
1079+ file_contents. push ( Cow :: Borrowed ( "" ) ) ;
10341080 }
10351081
10361082 file_contents. push ( Cow :: Owned ( format ! ( "class {type_name}:" ) ) ) ;
@@ -1055,7 +1101,7 @@ fn pyi_generator(type_data: &[(String, String, Vec<Vec<String>>)]) -> io::Result
10551101 } ;
10561102
10571103 if is_enum {
1058- file_contents. push ( Cow :: Owned ( format ! ( " {variable_name} = {variable_type}" , ) ) ) ;
1104+ file_contents. push ( Cow :: Owned ( format ! ( " {variable_name} = {type_name}({ variable_type})" ) ) ) ;
10591105 continue ;
10601106 }
10611107
@@ -1149,6 +1195,13 @@ fn pyi_generator(type_data: &[(String, String, Vec<Vec<String>>)]) -> io::Result
11491195 file_contents. push ( Cow :: Borrowed ( " def __str__(self) -> str: ..." ) ) ;
11501196 file_contents. push ( Cow :: Borrowed ( " def __repr__(self) -> str: ..." ) ) ;
11511197
1198+ if is_enum {
1199+ file_contents. push ( Cow :: Borrowed ( " def __int__(self) -> int: ..." ) ) ;
1200+ file_contents. push ( Cow :: Owned ( format ! (
1201+ " def __richcmp__(self, other: {type_name}, op: int) -> bool: ..."
1202+ ) ) ) ;
1203+ }
1204+
11521205 if !is_union {
11531206 file_contents. push ( Cow :: Borrowed ( " def pack(self) -> bytes: ..." ) ) ;
11541207 file_contents. push ( Cow :: Borrowed ( " @staticmethod" ) ) ;
@@ -1198,7 +1251,11 @@ fn main() -> io::Result<()> {
11981251
11991252 let out_folder = Path :: new ( OUT_FOLDER ) . join ( "rlbot" ) . join ( "flat" ) ;
12001253
1201- assert ! ( out_folder. exists( ) , "Could not find generated folder: {}" , out_folder. display( ) ) ;
1254+ assert ! (
1255+ out_folder. exists( ) ,
1256+ "Could not find generated folder: {}" ,
1257+ out_folder. display( )
1258+ ) ;
12021259
12031260 // ^ the above generates the Rust flatbuffers code,
12041261 // and the below we generates the wanted additional Python binds
0 commit comments