@@ -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
0 commit comments