Skip to content

Commit 45f7564

Browse files
committed
Add pack/unpack methods for structs
1 parent 362c3e2 commit 45f7564

16 files changed

Lines changed: 523 additions & 27 deletions

Cargo.lock

Lines changed: 13 additions & 13 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"
3-
version = "0.18.7"
3+
version = "0.18.8"
44
edition = "2024"
55
description = "A Python module implemented in Rust for serializing and deserializing RLBot's flatbuffers"
66
repository = "https://github.com/RLBot/flatbuffers-python"

codegen/pyi.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,21 @@ pub fn generator(type_data: &Declarations) -> io::Result<()> {
223223
" NOTE: All field initialization before `__init__`, inside of `__new__`."
224224
);
225225
write_str!(file, " \"\"\"");
226+
227+
write_str!(file, " def pack(self) -> bytes:");
228+
write_str!(file, " \"\"\"");
229+
write_str!(file, " Serializes this instance into a byte array");
230+
write_str!(file, " \"\"\"\n");
231+
232+
write_str!(file, " @staticmethod");
233+
write_fmt!(file, " def unpack(data: bytes) -> {type_name}:");
234+
write_str!(file, " \"\"\"");
235+
write_str!(file, " Deserializes the data into a new instance\n");
236+
write_str!(
237+
file,
238+
" :raises InvalidFlatbuffer: If the `data` is invalid for this type"
239+
);
240+
write_str!(file, " \"\"\"\n");
226241
}
227242
DeclarationKind::Table(info) => {
228243
for (field_name, field_info) in &info.fields {

codegen/structs.rs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ impl<'a> StructBindGenerator<'a> {
427427
}
428428

429429
write_str!(self, " )");
430-
write_str!(self, " }");
430+
write_str!(self, " }\n");
431431
}
432432

433433
fn generate_py_methods(&mut self) {
@@ -445,24 +445,91 @@ impl<'a> StructBindGenerator<'a> {
445445

446446
self.generate_args();
447447

448+
self.generate_pack_method();
449+
write_str!(self, "");
450+
451+
self.generate_unpack_method();
452+
448453
write_str!(self, "}");
449454
write_str!(self, "");
450455
}
451456

457+
fn generate_read_as_root(&mut self) {
458+
write_fmt!(
459+
self,
460+
"fn read_as_root<'a>(slice: &'a [u8]) -> ::planus::Result<flat::{}Ref<'a>> {{",
461+
self.name
462+
);
463+
write_str!(
464+
self,
465+
"planus::TableRead::from_buffer(planus::SliceWithStartOffset {"
466+
);
467+
write_str!(self, "buffer: slice, offset_from_start: 0 }, 0,");
468+
write_str!(self, ").map_err(|error_kind|");
469+
write_fmt!(
470+
self,
471+
"error_kind.with_error_location(\"[{}Ref]\", \"read_as_root\", 0)",
472+
self.name
473+
);
474+
write_str!(self, ")}\n");
475+
}
476+
477+
fn generate_pack_method(&mut self) {
478+
write_str!(
479+
self,
480+
" fn pack<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {"
481+
);
482+
write_str!(
483+
self,
484+
" let mut builder = Builder::with_capacity(u16::MAX as usize);\n"
485+
);
486+
write_fmt!(
487+
self,
488+
" let flat_t = flat::{}::from_gil(py, self);",
489+
self.name
490+
);
491+
write_str!(
492+
self,
493+
" PyBytes::new(py, builder.finish(flat_t, None))"
494+
);
495+
write_str!(self, " }");
496+
}
497+
498+
fn generate_unpack_method(&mut self) {
499+
write_str!(self, " #[staticmethod]");
500+
write_str!(
501+
self,
502+
" fn unpack(py: Python, data: &[u8]) -> PyResult<Py<Self>> {"
503+
);
504+
write_str!(
505+
self,
506+
" let flat_t_ref = read_as_root(data).map_err(flat_err_to_py)?;"
507+
);
508+
write_fmt!(
509+
self,
510+
" let flat_t = flat::{}::from(flat_t_ref);\n",
511+
self.name
512+
);
513+
write_str!(self, " Ok(crate::into_py_from(py, &flat_t))");
514+
write_str!(self, " }");
515+
}
516+
452517
pub fn generate_binds(mut self) -> Vec<Cow<'static, str>> {
453518
self.file_contents
454519
.push(Cow::Borrowed(if self.fields.is_empty() {
455-
"use crate::{FromGil, flat};"
520+
"use crate::{FromGil, flat_err_to_py, flat};"
456521
} else {
457-
"use crate::{FromGil, PyDefault, flat};"
522+
"use crate::{FromGil, PyDefault, flat, flat_err_to_py};"
458523
}));
459524

525+
write_str!(self, "use planus::{Builder, ReadAsRoot};");
460526
write_str!(self, "use pyo3::{prelude::*, types::*};");
461527
write_str!(self, "");
462528

463529
self.generate_definition();
464530
self.generate_from_flat_impls();
465531
self.generate_to_flat_impls();
532+
self.generate_read_as_root();
466533
self.generate_py_methods();
467534

468535
self.file_contents

pytest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def random_script_config():
4343
controller.throttle = 1
4444
controller.steer = 0.5
4545
controller.pitch = np.array([0.1], dtype=np.float32)[0]
46+
controller.pack()
4647

4748
vec1 = MyVector(1, 2, 3)
4849
vec2 = Vector3(4, 5, 6)

0 commit comments

Comments
 (0)