@@ -20,8 +20,12 @@ impl super::ToTypescript for syn::ItemEnum {
2020 let is_single = !self . variants . iter ( ) . any ( |x| !x. fields . is_empty ( ) ) ;
2121 state. write_comments ( & comments, 0 ) ;
2222
23+ // Handle untagged enum if serde has the tag untagged
24+ if utils:: get_attribute_arg ( "serde" , "untagged" , & self . attrs ) . is_some ( ) {
25+ add_untagged_tagged_enum ( self , state, casing, config. uses_type_interface ) ;
26+ }
2327 // always use output the internally_tagged representation if the tag is present
24- if let Some ( tag_name) = utils:: get_attribute_arg ( "serde" , "tag" , & self . attrs ) {
28+ else if let Some ( tag_name) = utils:: get_attribute_arg ( "serde" , "tag" , & self . attrs ) {
2529 let content_name = utils:: get_attribute_arg ( "serde" , "content" , & self . attrs ) ;
2630 add_internally_tagged_enum (
2731 tag_name,
@@ -398,3 +402,58 @@ fn add_externally_tagged_enum(
398402 }
399403 state. types . push_str ( ";\n " ) ;
400404}
405+
406+ fn add_untagged_tagged_enum (
407+ exported_struct : syn:: ItemEnum ,
408+ state : & mut BuildState ,
409+ casing : Option < Case > ,
410+ uses_type_interface : bool ,
411+ ) {
412+ let export = if uses_type_interface { "" } else { "export " } ;
413+ let generics = utils:: extract_struct_generics ( exported_struct. generics . clone ( ) ) ;
414+
415+ // Write type name and generics
416+ state. types . push_str ( & format ! (
417+ "{export}type {interface_name}{generics} =" ,
418+ interface_name = exported_struct. ident,
419+ generics = utils:: format_generics( & generics)
420+ ) ) ;
421+
422+ // Loop over each variant of the enum
423+ for variant in exported_struct. variants {
424+ state. types . push ( '\n' ) ;
425+ // Copy comments from rust
426+ let comments = utils:: get_comments ( variant. attrs ) ;
427+ state. write_comments ( & comments, 2 ) ;
428+
429+ // Unnamed fields:
430+ // ```rs
431+ // enum Data {
432+ // Value1(i32)
433+ // }
434+ // ```
435+ if let syn:: Fields :: Unnamed ( fields) = & variant. fields {
436+ // add discriminant
437+ state. types . push_str ( & format ! ( " | " ) ) ;
438+ super :: structs:: process_tuple_fields ( fields. clone ( ) , state) ;
439+ state. types . push_str ( "" ) ;
440+ }
441+ // Named fields:
442+ // ```rs
443+ // enum Data {
444+ // Value1 { v: i32 }
445+ // }
446+ // ```
447+ else {
448+ // add discriminant
449+ state. types . push_str ( & format ! ( " | {{\n " ) ) ;
450+
451+ super :: structs:: process_fields ( variant. fields , state, 6 , casing, true ) ;
452+
453+ state
454+ . types
455+ . push_str ( & format ! ( "{}}}" , utils:: build_indentation( 4 ) ) ) ;
456+ }
457+ }
458+ state. types . push_str ( ";\n " ) ;
459+ }
0 commit comments