@@ -2,7 +2,7 @@ use crate::ast;
2
2
use crate :: encode;
3
3
use crate :: Diagnostic ;
4
4
use once_cell:: sync:: Lazy ;
5
- use proc_macro2:: { Ident , Literal , Span , TokenStream } ;
5
+ use proc_macro2:: { Ident , Span , TokenStream } ;
6
6
use quote:: format_ident;
7
7
use quote:: quote_spanned;
8
8
use quote:: { quote, ToTokens } ;
@@ -1015,117 +1015,136 @@ impl ToTokens for ast::ImportType {
1015
1015
}
1016
1016
}
1017
1017
1018
- impl ToTokens for ast:: ImportEnum {
1018
+ impl ToTokens for ast:: StringEnum {
1019
1019
fn to_tokens ( & self , tokens : & mut TokenStream ) {
1020
1020
let vis = & self . vis ;
1021
- let name = & self . name ;
1022
- let expect_string = format ! ( "attempted to convert invalid {} into JSValue" , name) ;
1021
+ let enum_name = & self . name ;
1022
+ let name_str = enum_name. to_string ( ) ;
1023
+ let name_len = name_str. len ( ) as u32 ;
1024
+ let name_chars = name_str. chars ( ) . map ( u32:: from) ;
1023
1025
let variants = & self . variants ;
1024
- let variant_strings = & self . variant_values ;
1026
+ let variant_count = self . variant_values . len ( ) as u32 ;
1027
+ let variant_values = & self . variant_values ;
1028
+ let variant_indices = ( 0 ..variant_count) . collect :: < Vec < _ > > ( ) ;
1029
+ let invalid = variant_count;
1030
+ let hole = variant_count + 1 ;
1025
1031
let attrs = & self . rust_attrs ;
1026
1032
1027
- let mut current_idx: usize = 0 ;
1028
- let variant_indexes: Vec < Literal > = variants
1029
- . iter ( )
1030
- . map ( |_| {
1031
- let this_index = current_idx;
1032
- current_idx += 1 ;
1033
- Literal :: usize_unsuffixed ( this_index)
1034
- } )
1035
- . collect ( ) ;
1036
-
1037
- // Borrow variant_indexes because we need to use it multiple times inside the quote! macro
1038
- let variant_indexes_ref = & variant_indexes;
1033
+ let invalid_to_str_msg = format ! (
1034
+ "Converting an invalid string enum ({}) back to a string is currently not supported" ,
1035
+ enum_name
1036
+ ) ;
1039
1037
1040
1038
// A vector of EnumName::VariantName tokens for this enum
1041
1039
let variant_paths: Vec < TokenStream > = self
1042
1040
. variants
1043
1041
. iter ( )
1044
- . map ( |v| quote ! ( #name :: #v) . into_token_stream ( ) )
1042
+ . map ( |v| quote ! ( #enum_name :: #v) . into_token_stream ( ) )
1045
1043
. collect ( ) ;
1046
1044
1047
1045
// Borrow variant_paths because we need to use it multiple times inside the quote! macro
1048
1046
let variant_paths_ref = & variant_paths;
1049
1047
1050
1048
let wasm_bindgen = & self . wasm_bindgen ;
1051
1049
1050
+ let describe_variants = self . variant_values . iter ( ) . map ( |variant_value| {
1051
+ let length = variant_value. len ( ) as u32 ;
1052
+ let chars = variant_value. chars ( ) . map ( u32:: from) ;
1053
+ quote ! {
1054
+ inform( #length) ;
1055
+ #( inform( #chars) ; ) *
1056
+ }
1057
+ } ) ;
1058
+
1052
1059
( quote ! {
1053
1060
#( #attrs) *
1054
- #vis enum #name {
1055
- #( #variants = #variant_indexes_ref, ) *
1061
+ #[ non_exhaustive]
1062
+ #[ repr( u32 ) ]
1063
+ #vis enum #enum_name {
1064
+ #( #variants = #variant_indices, ) *
1056
1065
#[ automatically_derived]
1057
1066
#[ doc( hidden) ]
1058
- __Nonexhaustive ,
1067
+ __Invalid
1059
1068
}
1060
1069
1061
1070
#[ automatically_derived]
1062
- impl #name {
1063
- fn from_str( s: & str ) -> Option <#name > {
1071
+ impl #enum_name {
1072
+ fn from_str( s: & str ) -> Option <#enum_name > {
1064
1073
match s {
1065
- #( #variant_strings => Some ( #variant_paths_ref) , ) *
1074
+ #( #variant_values => Some ( #variant_paths_ref) , ) *
1066
1075
_ => None ,
1067
1076
}
1068
1077
}
1069
1078
1070
1079
fn to_str( & self ) -> & ' static str {
1071
1080
match self {
1072
- #( #variant_paths_ref => #variant_strings , ) *
1073
- #name :: __Nonexhaustive => panic!( #expect_string ) ,
1081
+ #( #variant_paths_ref => #variant_values , ) *
1082
+ #enum_name :: __Invalid => panic!( #invalid_to_str_msg ) ,
1074
1083
}
1075
1084
}
1076
1085
1077
- #vis fn from_js_value( obj: & #wasm_bindgen:: JsValue ) -> Option <#name > {
1086
+ #vis fn from_js_value( obj: & #wasm_bindgen:: JsValue ) -> Option <#enum_name > {
1078
1087
obj. as_string( ) . and_then( |obj_str| Self :: from_str( obj_str. as_str( ) ) )
1079
1088
}
1080
1089
}
1081
1090
1082
- // It should really be using &str for all of these, but that requires some major changes to cli-support
1083
1091
#[ automatically_derived]
1084
- impl #wasm_bindgen:: describe:: WasmDescribe for #name {
1085
- fn describe( ) {
1086
- <#wasm_bindgen:: JsValue as #wasm_bindgen:: describe:: WasmDescribe >:: describe( )
1087
- }
1088
- }
1089
-
1090
- #[ automatically_derived]
1091
- impl #wasm_bindgen:: convert:: IntoWasmAbi for #name {
1092
- type Abi = <#wasm_bindgen:: JsValue as #wasm_bindgen:: convert:: IntoWasmAbi >:: Abi ;
1092
+ impl #wasm_bindgen:: convert:: IntoWasmAbi for #enum_name {
1093
+ type Abi = u32 ;
1093
1094
1094
1095
#[ inline]
1095
- fn into_abi( self ) -> Self :: Abi {
1096
- <#wasm_bindgen :: JsValue as #wasm_bindgen :: convert :: IntoWasmAbi > :: into_abi ( self . into ( ) )
1096
+ fn into_abi( self ) -> u32 {
1097
+ self as u32
1097
1098
}
1098
1099
}
1099
1100
1100
1101
#[ automatically_derived]
1101
- impl #wasm_bindgen:: convert:: FromWasmAbi for #name {
1102
- type Abi = <#wasm_bindgen :: JsValue as #wasm_bindgen :: convert :: FromWasmAbi > :: Abi ;
1102
+ impl #wasm_bindgen:: convert:: FromWasmAbi for #enum_name {
1103
+ type Abi = u32 ;
1103
1104
1104
- unsafe fn from_abi( js: Self :: Abi ) -> Self {
1105
- let s = <#wasm_bindgen:: JsValue as #wasm_bindgen:: convert:: FromWasmAbi >:: from_abi( js) ;
1106
- #name:: from_js_value( & s) . unwrap_or( #name:: __Nonexhaustive)
1105
+ unsafe fn from_abi( val: u32 ) -> Self {
1106
+ match val {
1107
+ #( #variant_indices => #variant_paths_ref, ) *
1108
+ #invalid => #enum_name:: __Invalid,
1109
+ _ => unreachable!( "The JS binding should only ever produce a valid value or the specific 'invalid' value" ) ,
1110
+ }
1107
1111
}
1108
1112
}
1109
1113
1110
1114
#[ automatically_derived]
1111
- impl #wasm_bindgen:: convert:: OptionIntoWasmAbi for #name {
1115
+ impl #wasm_bindgen:: convert:: OptionFromWasmAbi for #enum_name {
1112
1116
#[ inline]
1113
- fn none ( ) -> Self :: Abi { < :: js_sys :: Object as #wasm_bindgen :: convert :: OptionIntoWasmAbi > :: none ( ) }
1117
+ fn is_none ( val : & u32 ) -> bool { * val == #hole }
1114
1118
}
1115
1119
1116
1120
#[ automatically_derived]
1117
- impl #wasm_bindgen:: convert:: OptionFromWasmAbi for #name {
1121
+ impl #wasm_bindgen:: convert:: OptionIntoWasmAbi for #enum_name {
1118
1122
#[ inline]
1119
- fn is_none( abi: & Self :: Abi ) -> bool { <:: js_sys:: Object as #wasm_bindgen:: convert:: OptionFromWasmAbi >:: is_none( abi) }
1123
+ fn none( ) -> Self :: Abi { #hole }
1124
+ }
1125
+
1126
+ #[ automatically_derived]
1127
+ impl #wasm_bindgen:: describe:: WasmDescribe for #enum_name {
1128
+ fn describe( ) {
1129
+ use #wasm_bindgen:: describe:: * ;
1130
+ inform( STRING_ENUM ) ;
1131
+ inform( #name_len) ;
1132
+ #( inform( #name_chars) ; ) *
1133
+ inform( #variant_count) ;
1134
+ #( #describe_variants) *
1135
+ }
1120
1136
}
1121
1137
1122
1138
#[ automatically_derived]
1123
- impl From <#name> for #wasm_bindgen:: JsValue {
1124
- fn from( obj: #name) -> #wasm_bindgen:: JsValue {
1125
- #wasm_bindgen:: JsValue :: from( obj. to_str( ) )
1139
+ impl #wasm_bindgen:: __rt:: core:: convert:: From <#enum_name> for
1140
+ #wasm_bindgen:: JsValue
1141
+ {
1142
+ fn from( val: #enum_name) -> Self {
1143
+ #wasm_bindgen:: JsValue :: from_str( val. to_str( ) )
1126
1144
}
1127
1145
}
1128
- } ) . to_tokens ( tokens) ;
1146
+ } )
1147
+ . to_tokens ( tokens) ;
1129
1148
}
1130
1149
}
1131
1150
0 commit comments