@@ -156,7 +156,7 @@ pub struct ConvertImport2Template {
156156#[ derive( Debug , Clone , askama:: Template ) ]
157157#[ template( ext = "txt" , source = r#"
158158{% for f in from_imports -%}
159- {% let i = loop.index - %}
159+ {% let i = loop.index %}
160160 #[cfg({{f.gate}})]
161161 mod {{from_source|lower}}_{{i}} {
162162 {{f.import|indent(4)}}
@@ -175,40 +175,79 @@ pub struct ConvertImport1Template {
175175#[ template( ext = "txt" , source = r#"// This file is auto-generated. Do not edit manually.
176176
177177
178- pub fn {{ty|lower}}_to_{{code_ty|lower}}(value: {{ty}}) -> {{code_ty}} {
178+ pub fn {{ty|lower}}_to_{{code_ty|lower}}(value: &{{ty}}) -> {{code_ty}} {
179+ {% if const_check -%}
180+ #[allow(unused_parens)]
179181 const {
180182 {% for entry in entries -%}
181- assert!({{to_code_prefix }}({{ value_prefix}}{{ entry.0 | pad_right(*k_len) }}{{value_suffix}} ){{to_code_suffix }} == {{entry.1 | hex}});
183+ assert!({{to_code_expr.0 }}(&{{"{" ~ value_prefix}}{{ entry.0 | pad_right(*k_len) }}{{value_suffix ~ "}"}} ){{to_code_expr.1 }} == {{entry.1 | hex}});
182184 {% endfor -%}
183185 }
184- {{to_code_prefix}}value{{to_code_suffix}}
186+ {% endif -%}
187+ {{to_code_expr.0}}value{{to_code_expr.1}}
188+ }
189+
190+ impl crate::numeric::AsCode<{{ty}}> for crate::numeric::Coder {
191+ type Code = {{code_ty}};
192+ fn as_code(value: &{{ty}}) -> Self::Code {
193+ {{ty|lower}}_to_{{code_ty|lower}}(value)
194+ }
195+ fn from_code(code: Self::Code) -> Option<{{ty}}> {
196+ match code {
197+ {% for entry in entries|unique -%}
198+ {{entry.1 | hex}} => Some({{value_prefix}}{{ entry.0 | pad_right(*k_len) }}{{value_suffix}}),
199+ {% endfor -%}
200+ _ => None,
201+ }
202+ }
203+ {% if let Some(from_code_expr) = from_code_expr -%}
204+ unsafe fn from_code_unchecked(code: Self::Code) -> {{ty}} {
205+ {{from_code_expr.0}}code{{from_code_expr.1}}
206+ }
207+ {% endif -%}
208+ }
209+
210+ {% if !const_check -%}
211+ #[test]
212+ #[allow(unused_parens)]
213+ fn test_code() {
214+ {% for entry in entries -%}
215+ assert!({{to_code_expr.0}}(&{{"{" ~ value_prefix}}{{ entry.0 | pad_right(*k_len) }}{{value_suffix ~ "}"}}){{to_code_expr.1}} == {{entry.1 | hex}});
216+ {% endfor -%}
185217}
218+ {% endif -%}
186219"# ) ]
187220pub struct AsCodeImplTemplate < ' a > {
188221 pub ty : & ' a str ,
189222 pub code_ty : & ' a str ,
190- pub to_code_prefix : & ' a str ,
191- pub to_code_suffix : & ' a str ,
223+ pub from_code_expr : Option < ( & ' a str , & ' a str ) > ,
224+ pub to_code_expr : ( & ' a str , & ' a str ) ,
225+ pub const_check : bool ,
192226 pub value_prefix : & ' a str ,
193227 pub value_suffix : & ' a str ,
194228 pub k_len : usize ,
195229 pub entries : Vec < ( Cow < ' a , str > , u64 ) > ,
196230}
197231impl < ' a > AsCodeImplTemplate < ' a > {
198- pub fn create ( from : & ' a str , to : & ' a str , to_code_expr : Option < & ' a str > , prefix : Option < & ' a str > , suffix : Option < & ' a str > ) -> Self {
232+ fn split_expr ( s : & ' a str ) -> ( & ' a str , & ' a str ) {
233+ if s. contains ( "{}" ) {
234+ s. split_once ( "{}" ) . unwrap ( )
235+ } else {
236+ ( "" , s)
237+ }
238+ }
239+ pub fn create ( from : & ' a str , to : & ' a str , const_check : bool , from_code_expr : Option < & ' a str > , to_code_expr : Option < & ' a str > , prefix : Option < & ' a str > , suffix : Option < & ' a str > ) -> Self {
199240 let prefix = prefix. unwrap_or ( "" ) ;
200241 let suffix = suffix. unwrap_or ( "" ) ;
201242 let to_code_expr = to_code_expr. unwrap_or ( "{}" ) ;
202- let ( to_code_prefix, to_code_suffix) = if to_code_expr. contains ( "{}" ) {
203- to_code_expr. split_once ( "{}" ) . unwrap ( )
204- } else {
205- ( "" , to_code_expr)
206- } ;
243+ let to_code_expr = Self :: split_expr ( to_code_expr) ;
244+ let from_code_expr = from_code_expr. map ( Self :: split_expr) ;
207245 Self {
208246 ty : from,
209247 code_ty : to,
210- to_code_prefix,
211- to_code_suffix,
248+ const_check,
249+ from_code_expr,
250+ to_code_expr,
212251 value_prefix : prefix,
213252 value_suffix : suffix,
214253 entries : vec ! [ ] ,
@@ -324,15 +363,23 @@ impl KeyType {
324363 }
325364 }
326365
327- pub fn as_code_expr ( self ) -> Option < & ' static str > {
366+ pub fn as_to_code_expr ( self ) -> Option < & ' static str > {
328367 match self {
329368 KeyType :: HUT => Some ( "AsUsage::usage_value({})" ) ,
330- KeyType :: Winput => Some ( "{} as u8" ) ,
369+ KeyType :: Winput => Some ( "* {} as u8" ) ,
331370 KeyType :: WinVk => Some ( "{}.0" ) ,
332371 _ => None ,
333372 }
334373 }
335374
375+ pub fn as_from_code_expr ( self ) -> Option < & ' static str > {
376+ match self {
377+ KeyType :: HUT => None ,
378+ KeyType :: Winput | KeyType :: WinVk => Some ( "unsafe { crate::numeric::convert_from_code_unchecked({}) }" ) ,
379+ _ => None ,
380+ }
381+ }
382+
336383 pub fn as_code_type ( self ) -> Option < & ' static str > {
337384 match self {
338385 KeyType :: HUT => Some ( "u32" ) ,
@@ -342,6 +389,15 @@ impl KeyType {
342389 }
343390 }
344391
392+ pub fn can_const_check ( self ) -> bool {
393+ match self {
394+ KeyType :: HUT => false ,
395+ KeyType :: Winput => true ,
396+ KeyType :: WinVk => true ,
397+ _ => false ,
398+ }
399+ }
400+
345401 pub fn is_valid < S : AsRef < str > > ( self , s : S ) -> bool {
346402 let s = s. as_ref ( ) . trim ( ) ;
347403 !s. is_empty ( ) && !s. starts_with ( "n!" ) && !s. starts_with ( "na!" ) && !s. starts_with ( "todo!" ) && !s. starts_with ( "none!" )
@@ -433,7 +489,7 @@ impl Gen {
433489 if content. trim ( ) . is_empty ( ) {
434490 return String :: new ( ) ;
435491 }
436- format ! ( "mod generated_{} {{\n {}\n }}\n \n " , format!( "{:?}" , from) . to_lowercase( ) , content. trim( ) )
492+ format ! ( "#[allow(unused_imports)] \n mod generated_{} {{\n {}\n }}\n \n " , format!( "{:?}" , from) . to_lowercase( ) , content. trim( ) )
437493 }
438494
439495 pub fn build_imports2 ( self , filename : & str ) -> String {
@@ -496,7 +552,7 @@ impl Gen {
496552 }
497553 Some ( ( from. parse_content_unchecked ( k) , to. parse_code_unchecked ( v) ) )
498554 } ) . collect :: < Vec < _ > > ( ) ;
499- AsCodeImplTemplate :: create ( from. name ( ) , to_type, to. as_code_expr ( ) , from. as_value_prefix ( ) , from. as_value_suffix ( ) )
555+ AsCodeImplTemplate :: create ( from. name ( ) , to_type, from . can_const_check ( ) , to. as_from_code_expr ( ) , to . as_to_code_expr ( ) , from. as_value_prefix ( ) , from. as_value_suffix ( ) )
500556 . build ( map)
501557 }
502558}
@@ -586,7 +642,7 @@ pub fn main() {
586642 save_file ( format ! ( "{output_path}/generated._index.rs" ) , index_mod) . expect ( "failed to write index.rs" ) ;
587643
588644 let mut index_mod = String :: new ( ) ;
589- for ty in [ KeyType :: Winput ] {
645+ for ty in [ KeyType :: HUT , KeyType :: Winput , KeyType :: WinVk ] {
590646 let filename = format ! ( "generated.{ty:?}.rs" ) ;
591647 let content = Gen ( ty, ty) . build_as_code ( & csv) ;
592648 save_file ( format ! ( "{output_path2}/{filename}" ) , content)
0 commit comments