@@ -9,7 +9,7 @@ use wit_bindgen_core::wit_parser::{
9
9
Variant , World , WorldItem , WorldKey ,
10
10
} ;
11
11
use wit_bindgen_core:: { uwrite, uwriteln, Source , TypeInfo } ;
12
- use wrpc_introspect:: { async_paths_ty, flag_repr , is_list_of, is_ty, rpc_func_name} ;
12
+ use wrpc_introspect:: { async_paths_ty, is_list_of, is_ty, rpc_func_name} ;
13
13
14
14
use crate :: {
15
15
to_go_ident, to_package_ident, to_upper_camel_case, Deps , GoWrpc , Identifier , InterfaceName ,
@@ -737,37 +737,20 @@ impl InterfaceGenerator<'_> {
737
737
self . src . push_str ( ")" ) ;
738
738
}
739
739
740
- fn print_read_flags ( & mut self , ty : & Flags , reader : & str , name : & str ) {
741
- let fmt = self . deps . fmt ( ) ;
742
- let io = self . deps . io ( ) ;
743
-
744
- let repr = flag_repr ( ty) ;
740
+ fn print_read_flags ( & mut self , reader : & str , name : & str ) {
741
+ let wrpc = self . deps . wrpc ( ) ;
745
742
746
743
uwrite ! (
747
744
self . src,
748
- r#"func(r {io}.ByteReader) (*{name}, error) {{
749
- v := &{name}{{}}
750
- n, err := "#
745
+ r#"func(r {wrpc}.IndexReader) (*{name}, error) {{
746
+ v := {name}{{}}
747
+ if err := v.ReadFromIndex(r); err != nil {{
748
+ return nil, err
749
+ }}
750
+ return &v, nil
751
+ }}({reader})
752
+ "#
751
753
) ;
752
- self . print_read_discriminant ( repr, "r" ) ;
753
- self . push_str ( "\n " ) ;
754
- self . push_str ( "if err != nil {\n " ) ;
755
- self . push_str ( "return nil, " ) ;
756
- self . push_str ( fmt) ;
757
- self . push_str ( ".Errorf(\" failed to read flag: %w\" , err)\n " ) ;
758
- self . push_str ( "}\n " ) ;
759
- for ( i, Flag { name, .. } ) in ty. flags . iter ( ) . enumerate ( ) {
760
- if i > 64 {
761
- break ;
762
- }
763
- uwriteln ! ( self . src, "if n & (1 << {i}) > 0 {{" ) ;
764
- self . push_str ( "v." ) ;
765
- self . push_str ( & name. to_upper_camel_case ( ) ) ;
766
- self . push_str ( " = true\n " ) ;
767
- self . push_str ( "}\n " ) ;
768
- }
769
- self . push_str ( "return v, nil\n " ) ;
770
- uwrite ! ( self . src, "}}({reader})" ) ;
771
754
}
772
755
773
756
fn print_read_enum ( & mut self , ty : & Enum , reader : & str , name : & str ) {
@@ -1328,8 +1311,8 @@ impl InterfaceGenerator<'_> {
1328
1311
TypeDefKind :: Resource => self . print_read_string ( reader) ,
1329
1312
TypeDefKind :: Handle ( Handle :: Own ( id) ) => self . print_read_own ( reader, * id) ,
1330
1313
TypeDefKind :: Handle ( Handle :: Borrow ( id) ) => self . print_read_borrow ( reader, * id) ,
1331
- TypeDefKind :: Flags ( ty ) => {
1332
- self . print_read_flags ( ty , reader, & name. expect ( "flag missing a name" ) ) ;
1314
+ TypeDefKind :: Flags ( _ty ) => {
1315
+ self . print_read_flags ( reader, & name. expect ( "flag missing a name" ) ) ;
1333
1316
}
1334
1317
TypeDefKind :: Tuple ( ty) => self . print_read_tuple ( ty, reader, path) ,
1335
1318
TypeDefKind :: Variant ( ty) => {
@@ -3743,13 +3726,13 @@ func (v *{name}) WriteToIndex(w {wrpc}.ByteWriter) (func({wrpc}.IndexWriter) err
3743
3726
}
3744
3727
3745
3728
fn type_flags ( & mut self , id : TypeId , _name : & str , ty : & Flags , docs : & Docs ) {
3746
- let repr = flag_repr ( ty) ;
3747
-
3748
3729
let info = self . info ( id) ;
3749
3730
if let Some ( name) = self . name_of ( id) {
3750
3731
let strings = self . deps . strings ( ) ;
3751
3732
let wrpc = self . deps . wrpc ( ) ;
3733
+ let errors = self . deps . errors ( ) ;
3752
3734
3735
+ // Struct
3753
3736
self . godoc ( docs) ;
3754
3737
uwriteln ! ( self . src, "type {name} struct {{" ) ;
3755
3738
for Flag { name, docs } in & ty. flags {
@@ -3759,6 +3742,7 @@ func (v *{name}) WriteToIndex(w {wrpc}.ByteWriter) (func({wrpc}.IndexWriter) err
3759
3742
}
3760
3743
self . push_str ( "}\n " ) ;
3761
3744
3745
+ // String()
3762
3746
uwriteln ! ( self . src, "func (v *{name}) String() string {{" ) ;
3763
3747
uwriteln ! ( self . src, "flags := make([]string, 0, {})" , ty. flags. len( ) ) ;
3764
3748
for Flag { name, .. } in & ty. flags {
@@ -3769,34 +3753,76 @@ func (v *{name}) WriteToIndex(w {wrpc}.ByteWriter) (func({wrpc}.IndexWriter) err
3769
3753
self . push_str ( "}\n " ) ;
3770
3754
}
3771
3755
uwriteln ! ( self . src, r#"return {strings}.Join(flags, " | ")"# ) ;
3772
- self . push_str ( "}\n " ) ;
3756
+ self . push_str ( "}\n \n " ) ;
3757
+
3758
+ // WriteToIndex()
3759
+ let mut buf_len = ty. flags . len ( ) / 8 ;
3760
+ if ty. flags . len ( ) % 8 > 0 {
3761
+ buf_len += 1 ;
3762
+ }
3763
+
3773
3764
uwriteln ! (
3774
3765
self . src,
3775
- "func (v *{name}) WriteToIndex(w {wrpc}.ByteWriter) (func({wrpc}.IndexWriter) error, error) {{"
3766
+ r#"func (v *{name}) WriteToIndex(w {wrpc}.ByteWriter) (func({wrpc}.IndexWriter) error, error) {{
3767
+ var p [{buf_len}]byte
3768
+ "#
3776
3769
) ;
3777
- self . push_str ( "var n " ) ;
3778
- self . int_repr ( repr) ;
3779
- self . push_str ( "\n " ) ;
3770
+
3780
3771
for ( i, Flag { name, .. } ) in ty. flags . iter ( ) . enumerate ( ) {
3781
3772
self . push_str ( "if v." ) ;
3782
3773
self . push_str ( & name. to_upper_camel_case ( ) ) ;
3783
- self . push_str ( " {\n " ) ;
3784
- if i <= 64 {
3785
- uwriteln ! ( self . src, "n |= 1 << {i}" ) ;
3786
- } else {
3787
- let errors = self . deps . errors ( ) ;
3788
- uwriteln ! (
3789
- self . src,
3790
- r#"return nil, {errors}.New("encoding `{name}` flag value would overflow 64-bit integer, flags containing more than 64 members are not supported yet")"#
3791
- ) ;
3792
- }
3793
- self . push_str ( "}\n " ) ;
3774
+ uwriteln ! (
3775
+ self . src,
3776
+ r#"{{
3777
+ p[{}] |= 1 << {}
3778
+ }}"# ,
3779
+ i / 8 ,
3780
+ i % 8
3781
+ ) ;
3794
3782
}
3795
- self . push_str ( "return nil, " ) ;
3796
- self . print_write_discriminant ( repr, "n" , "w" ) ;
3797
- self . push_str ( "\n " ) ;
3798
- self . push_str ( "}\n " ) ;
3783
+ uwriteln ! (
3784
+ self . src,
3785
+ r#"
3786
+ _, err := w.Write(p[:])
3787
+ return nil, err
3788
+ }}
3789
+ "# ,
3790
+ ) ;
3791
+
3792
+ // ReadFromIndex()
3793
+ uwrite ! (
3794
+ self . src,
3795
+ r#"func (v *{name}) ReadFromIndex(r {wrpc}.IndexReader) error {{
3796
+ var p [{buf_len}]byte
3797
+ if _, err := r.Read(p[:]); err != nil {{
3798
+ return err
3799
+ }}
3800
+
3801
+ "#
3802
+ ) ;
3803
+
3804
+ for ( i, Flag { name, .. } ) in ty. flags . iter ( ) . enumerate ( ) {
3805
+ uwriteln ! (
3806
+ self . src,
3807
+ "v.{} = p[{}] & (1 << {}) > 0" ,
3808
+ name. to_upper_camel_case( ) ,
3809
+ i / 8 ,
3810
+ i % 8
3811
+ ) ;
3812
+ }
3813
+
3814
+ uwriteln ! (
3815
+ self . src,
3816
+ r#"
3817
+ if (p[{}] >> {}) > 0 {{
3818
+ return {errors}.New("bit not associated with any flag is set")
3819
+ }}"# ,
3820
+ buf_len - 1 ,
3821
+ ty. flags. len( ) % 8 ,
3822
+ ) ;
3823
+ self . push_str ( "return nil\n }\n " ) ;
3799
3824
3825
+ // Error()
3800
3826
if info. error {
3801
3827
uwriteln ! (
3802
3828
self . src,
0 commit comments