@@ -3,7 +3,7 @@ use crate::encode;
3
3
use crate :: encode:: EncodeChunk ;
4
4
use crate :: Diagnostic ;
5
5
use once_cell:: sync:: Lazy ;
6
- use proc_macro2:: { Ident , Literal , Span , TokenStream } ;
6
+ use proc_macro2:: { Ident , Span , TokenStream } ;
7
7
use quote:: format_ident;
8
8
use quote:: quote_spanned;
9
9
use quote:: { quote, ToTokens } ;
@@ -1075,117 +1075,136 @@ impl ToTokens for ast::ImportType {
1075
1075
}
1076
1076
}
1077
1077
1078
- impl ToTokens for ast:: ImportEnum {
1078
+ impl ToTokens for ast:: StringEnum {
1079
1079
fn to_tokens ( & self , tokens : & mut TokenStream ) {
1080
1080
let vis = & self . vis ;
1081
- let name = & self . name ;
1082
- let expect_string = format ! ( "attempted to convert invalid {} into JSValue" , name) ;
1081
+ let enum_name = & self . name ;
1082
+ let name_str = enum_name. to_string ( ) ;
1083
+ let name_len = name_str. len ( ) as u32 ;
1084
+ let name_chars = name_str. chars ( ) . map ( u32:: from) ;
1083
1085
let variants = & self . variants ;
1084
- let variant_strings = & self . variant_values ;
1086
+ let variant_count = self . variant_values . len ( ) as u32 ;
1087
+ let variant_values = & self . variant_values ;
1088
+ let variant_indices = ( 0 ..variant_count) . collect :: < Vec < _ > > ( ) ;
1089
+ let invalid = variant_count;
1090
+ let hole = variant_count + 1 ;
1085
1091
let attrs = & self . rust_attrs ;
1086
1092
1087
- let mut current_idx: usize = 0 ;
1088
- let variant_indexes: Vec < Literal > = variants
1089
- . iter ( )
1090
- . map ( |_| {
1091
- let this_index = current_idx;
1092
- current_idx += 1 ;
1093
- Literal :: usize_unsuffixed ( this_index)
1094
- } )
1095
- . collect ( ) ;
1096
-
1097
- // Borrow variant_indexes because we need to use it multiple times inside the quote! macro
1098
- let variant_indexes_ref = & variant_indexes;
1093
+ let invalid_to_str_msg = format ! (
1094
+ "Converting an invalid string enum ({}) back to a string is currently not supported" ,
1095
+ enum_name
1096
+ ) ;
1099
1097
1100
1098
// A vector of EnumName::VariantName tokens for this enum
1101
1099
let variant_paths: Vec < TokenStream > = self
1102
1100
. variants
1103
1101
. iter ( )
1104
- . map ( |v| quote ! ( #name :: #v) . into_token_stream ( ) )
1102
+ . map ( |v| quote ! ( #enum_name :: #v) . into_token_stream ( ) )
1105
1103
. collect ( ) ;
1106
1104
1107
1105
// Borrow variant_paths because we need to use it multiple times inside the quote! macro
1108
1106
let variant_paths_ref = & variant_paths;
1109
1107
1110
1108
let wasm_bindgen = & self . wasm_bindgen ;
1111
1109
1110
+ let describe_variants = self . variant_values . iter ( ) . map ( |variant_value| {
1111
+ let length = variant_value. len ( ) as u32 ;
1112
+ let chars = variant_value. chars ( ) . map ( u32:: from) ;
1113
+ quote ! {
1114
+ inform( #length) ;
1115
+ #( inform( #chars) ; ) *
1116
+ }
1117
+ } ) ;
1118
+
1112
1119
( quote ! {
1113
1120
#( #attrs) *
1114
- #vis enum #name {
1115
- #( #variants = #variant_indexes_ref, ) *
1121
+ #[ non_exhaustive]
1122
+ #[ repr( u32 ) ]
1123
+ #vis enum #enum_name {
1124
+ #( #variants = #variant_indices, ) *
1116
1125
#[ automatically_derived]
1117
1126
#[ doc( hidden) ]
1118
- __Nonexhaustive ,
1127
+ __Invalid
1119
1128
}
1120
1129
1121
1130
#[ automatically_derived]
1122
- impl #name {
1123
- fn from_str( s: & str ) -> Option <#name > {
1131
+ impl #enum_name {
1132
+ fn from_str( s: & str ) -> Option <#enum_name > {
1124
1133
match s {
1125
- #( #variant_strings => Some ( #variant_paths_ref) , ) *
1134
+ #( #variant_values => Some ( #variant_paths_ref) , ) *
1126
1135
_ => None ,
1127
1136
}
1128
1137
}
1129
1138
1130
1139
fn to_str( & self ) -> & ' static str {
1131
1140
match self {
1132
- #( #variant_paths_ref => #variant_strings , ) *
1133
- #name :: __Nonexhaustive => panic!( #expect_string ) ,
1141
+ #( #variant_paths_ref => #variant_values , ) *
1142
+ #enum_name :: __Invalid => panic!( #invalid_to_str_msg ) ,
1134
1143
}
1135
1144
}
1136
1145
1137
- #vis fn from_js_value( obj: & #wasm_bindgen:: JsValue ) -> Option <#name > {
1146
+ #vis fn from_js_value( obj: & #wasm_bindgen:: JsValue ) -> Option <#enum_name > {
1138
1147
obj. as_string( ) . and_then( |obj_str| Self :: from_str( obj_str. as_str( ) ) )
1139
1148
}
1140
1149
}
1141
1150
1142
- // It should really be using &str for all of these, but that requires some major changes to cli-support
1143
1151
#[ automatically_derived]
1144
- impl #wasm_bindgen:: describe:: WasmDescribe for #name {
1145
- fn describe( ) {
1146
- <#wasm_bindgen:: JsValue as #wasm_bindgen:: describe:: WasmDescribe >:: describe( )
1147
- }
1148
- }
1149
-
1150
- #[ automatically_derived]
1151
- impl #wasm_bindgen:: convert:: IntoWasmAbi for #name {
1152
- type Abi = <#wasm_bindgen:: JsValue as #wasm_bindgen:: convert:: IntoWasmAbi >:: Abi ;
1152
+ impl #wasm_bindgen:: convert:: IntoWasmAbi for #enum_name {
1153
+ type Abi = u32 ;
1153
1154
1154
1155
#[ inline]
1155
- fn into_abi( self ) -> Self :: Abi {
1156
- <#wasm_bindgen :: JsValue as #wasm_bindgen :: convert :: IntoWasmAbi > :: into_abi ( self . into ( ) )
1156
+ fn into_abi( self ) -> u32 {
1157
+ self as u32
1157
1158
}
1158
1159
}
1159
1160
1160
1161
#[ automatically_derived]
1161
- impl #wasm_bindgen:: convert:: FromWasmAbi for #name {
1162
- type Abi = <#wasm_bindgen :: JsValue as #wasm_bindgen :: convert :: FromWasmAbi > :: Abi ;
1162
+ impl #wasm_bindgen:: convert:: FromWasmAbi for #enum_name {
1163
+ type Abi = u32 ;
1163
1164
1164
- unsafe fn from_abi( js: Self :: Abi ) -> Self {
1165
- let s = <#wasm_bindgen:: JsValue as #wasm_bindgen:: convert:: FromWasmAbi >:: from_abi( js) ;
1166
- #name:: from_js_value( & s) . unwrap_or( #name:: __Nonexhaustive)
1165
+ unsafe fn from_abi( val: u32 ) -> Self {
1166
+ match val {
1167
+ #( #variant_indices => #variant_paths_ref, ) *
1168
+ #invalid => #enum_name:: __Invalid,
1169
+ _ => unreachable!( "The JS binding should only ever produce a valid value or the specific 'invalid' value" ) ,
1170
+ }
1167
1171
}
1168
1172
}
1169
1173
1170
1174
#[ automatically_derived]
1171
- impl #wasm_bindgen:: convert:: OptionIntoWasmAbi for #name {
1175
+ impl #wasm_bindgen:: convert:: OptionFromWasmAbi for #enum_name {
1172
1176
#[ inline]
1173
- fn none ( ) -> Self :: Abi { < :: js_sys :: Object as #wasm_bindgen :: convert :: OptionIntoWasmAbi > :: none ( ) }
1177
+ fn is_none ( val : & u32 ) -> bool { * val == #hole }
1174
1178
}
1175
1179
1176
1180
#[ automatically_derived]
1177
- impl #wasm_bindgen:: convert:: OptionFromWasmAbi for #name {
1181
+ impl #wasm_bindgen:: convert:: OptionIntoWasmAbi for #enum_name {
1178
1182
#[ inline]
1179
- fn is_none( abi: & Self :: Abi ) -> bool { <:: js_sys:: Object as #wasm_bindgen:: convert:: OptionFromWasmAbi >:: is_none( abi) }
1183
+ fn none( ) -> Self :: Abi { #hole }
1184
+ }
1185
+
1186
+ #[ automatically_derived]
1187
+ impl #wasm_bindgen:: describe:: WasmDescribe for #enum_name {
1188
+ fn describe( ) {
1189
+ use #wasm_bindgen:: describe:: * ;
1190
+ inform( STRING_ENUM ) ;
1191
+ inform( #name_len) ;
1192
+ #( inform( #name_chars) ; ) *
1193
+ inform( #variant_count) ;
1194
+ #( #describe_variants) *
1195
+ }
1180
1196
}
1181
1197
1182
1198
#[ automatically_derived]
1183
- impl From <#name> for #wasm_bindgen:: JsValue {
1184
- fn from( obj: #name) -> #wasm_bindgen:: JsValue {
1185
- #wasm_bindgen:: JsValue :: from( obj. to_str( ) )
1199
+ impl #wasm_bindgen:: __rt:: core:: convert:: From <#enum_name> for
1200
+ #wasm_bindgen:: JsValue
1201
+ {
1202
+ fn from( val: #enum_name) -> Self {
1203
+ #wasm_bindgen:: JsValue :: from_str( val. to_str( ) )
1186
1204
}
1187
1205
}
1188
- } ) . to_tokens ( tokens) ;
1206
+ } )
1207
+ . to_tokens ( tokens) ;
1189
1208
}
1190
1209
}
1191
1210
0 commit comments