@@ -226,18 +226,26 @@ impl std::fmt::Debug for DeferredTrace {
226226 }
227227}
228228
229+ #[ doc( hidden) ]
230+ #[ derive( Debug , Clone ) ]
231+ pub struct Enum {
232+ pub name : & ' static str ,
233+ pub output : Option < & ' static str > ,
234+ pub namespace : & ' static str ,
235+ }
236+
229237#[ doc( hidden) ]
230238#[ derive( Clone ) ]
231239pub struct DeferredEnumTrace {
232- pub name : & ' static str ,
240+ pub enum_data : Enum ,
233241 pub namespace : & ' static str ,
234242 pub trace : fn ( tracer : & mut serde_reflection:: Tracer ) ,
235243}
236244
237245impl std:: fmt:: Debug for DeferredEnumTrace {
238246 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
239247 f. debug_struct ( "DeferredEnumTrace" )
240- . field ( "name " , & self . name )
248+ . field ( "enum_data " , & self . enum_data )
241249 . field ( "namespace" , & self . namespace )
242250 . finish ( )
243251 }
@@ -264,8 +272,10 @@ pub struct Membrane {
264272 namespaces : Vec < & ' static str > ,
265273 namespaced_registry : HashMap < & ' static str , serde_reflection:: Result < Registry > > ,
266274 namespaced_fn_registry : HashMap < & ' static str , Vec < Function > > ,
275+ namespaced_enum_registry : HashMap < & ' static str , Vec < Enum > > ,
267276 generated : bool ,
268277 c_style_enums : bool ,
278+ sealed_enums : bool ,
269279 timeout : Option < i32 > ,
270280 borrows : Borrows ,
271281 _inputs : Vec < libloading:: Library > ,
@@ -346,7 +356,7 @@ impl<'a> Membrane {
346356 ) ;
347357 }
348358
349- enums. sort_by_cached_key ( |e| & e. name ) ;
359+ enums. sort_by_cached_key ( |e| & e. enum_data . name ) ;
350360
351361 functions. sort_by_cached_key ( |f| {
352362 format ! (
@@ -367,6 +377,7 @@ impl<'a> Membrane {
367377 let mut namespaced_registry = HashMap :: new ( ) ;
368378 let mut namespaced_samples = HashMap :: new ( ) ;
369379 let mut namespaced_fn_registry = HashMap :: new ( ) ;
380+ let mut namespaced_enum_registry = HashMap :: new ( ) ;
370381 let mut borrows: Borrows = HashMap :: new ( ) ;
371382
372383 // collect all the metadata about functions (without tracing them yet)
@@ -382,6 +393,14 @@ impl<'a> Membrane {
382393 Self :: create_borrows ( & namespaced_fn_registry, namespace, & mut borrows) ;
383394 } ) ;
384395
396+ // collect all the metadata about functions (without tracing them yet)
397+ enums. iter ( ) . for_each ( |item| {
398+ namespaced_enum_registry
399+ . entry ( item. namespace )
400+ . or_insert_with ( Vec :: new)
401+ . push ( item. enum_data . clone ( ) ) ;
402+ } ) ;
403+
385404 // trace all the enums at least once
386405 enums. iter ( ) . for_each ( |item| {
387406 // trace the enum into the borrowing namespace's registry
@@ -390,7 +409,7 @@ impl<'a> Membrane {
390409 . into_iter ( )
391410 . for_each ( |( for_namespace, from_namespaces) | {
392411 if let Some ( ( types, _location) ) = from_namespaces. get ( item. namespace ) {
393- if types. contains ( item. name ) {
412+ if types. contains ( item. enum_data . name ) {
394413 let tracer = namespaced_registry
395414 . entry ( for_namespace)
396415 . or_insert_with ( || Tracer :: new ( TracerConfig :: default ( ) ) ) ;
@@ -449,9 +468,11 @@ impl<'a> Membrane {
449468 . map ( |( key, val) | ( key, val. registry ( ) ) )
450469 . collect ( ) ,
451470 namespaced_fn_registry,
471+ namespaced_enum_registry,
452472 namespaces,
453473 generated : false ,
454474 c_style_enums : true ,
475+ sealed_enums : true ,
455476 timeout : None ,
456477 borrows,
457478 _inputs : input_libs,
@@ -544,7 +565,24 @@ impl<'a> Membrane {
544565 debug ! ( "Generating lib/src/ code for namespace {}" , namespace) ;
545566 let config = serde_generate:: CodeGeneratorConfig :: new ( namespace. to_string ( ) )
546567 . with_encodings ( vec ! [ serde_generate:: Encoding :: Bincode ] )
547- . with_c_style_enums ( self . c_style_enums ) ;
568+ . with_c_style_enums ( self . c_style_enums )
569+ . with_sealed_enums ( self . sealed_enums )
570+ . with_enum_type_overrides (
571+ self
572+ . namespaced_enum_registry
573+ . get ( namespace)
574+ . into_iter ( )
575+ . flat_map ( |enums| {
576+ enums. iter ( ) . filter_map ( |x| {
577+ if x. output . is_some ( ) {
578+ Some ( ( x. name , x. output . unwrap ( ) ) )
579+ } else {
580+ None
581+ }
582+ } )
583+ } )
584+ . collect :: < HashMap < & ' static str , & ' static str > > ( ) ,
585+ ) ;
548586
549587 let registry = match self . namespaced_registry . get ( namespace) . unwrap ( ) {
550588 Ok ( reg) => reg,
@@ -604,6 +642,16 @@ impl<'a> Membrane {
604642 self
605643 }
606644
645+ ///
646+ /// When set to `true` (the default) we generate sealed classes for complex enums
647+ /// instead of abstract classes. When set to `false`
648+ /// abstract classes are generated.
649+ pub fn with_sealed_enums ( & mut self , val : bool ) -> & mut Self {
650+ return_if_error ! ( self ) ;
651+ self . sealed_enums = val;
652+ self
653+ }
654+
607655 ///
608656 /// Configures the global timeout for non-stream receive ports.
609657 /// Streams do not use the global timeout as it is unusual to want a stream to timeout
0 commit comments