@@ -875,11 +875,10 @@ impl Default for StringOrBool {
875875 }
876876}
877877
878- #[ derive( Clone , Debug , Deserialize , PartialEq , Eq ) ]
879- #[ serde( untagged) ]
878+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
880879pub enum RustOptimize {
881- #[ serde( deserialize_with = "deserialize_and_validate_opt_level" ) ]
882880 String ( String ) ,
881+ Int ( u8 ) ,
883882 Bool ( bool ) ,
884883}
885884
@@ -889,26 +888,74 @@ impl Default for RustOptimize {
889888 }
890889}
891890
892- fn deserialize_and_validate_opt_level < ' de , D > ( d : D ) -> Result < String , D :: Error >
893- where
894- D : serde:: de:: Deserializer < ' de > ,
895- {
896- let v = String :: deserialize ( d) ?;
897- if [ "0" , "1" , "2" , "3" , "s" , "z" ] . iter ( ) . find ( |x| * * x == v) . is_some ( ) {
898- Ok ( v)
899- } else {
900- Err ( format ! ( r#"unrecognized option for rust optimize: "{}", expected one of "0", "1", "2", "3", "s", "z""# , v) ) . map_err ( serde:: de:: Error :: custom)
891+ impl < ' de > Deserialize < ' de > for RustOptimize {
892+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
893+ where
894+ D : Deserializer < ' de > ,
895+ {
896+ deserializer. deserialize_any ( OptimizeVisitor )
897+ }
898+ }
899+
900+ struct OptimizeVisitor ;
901+
902+ impl < ' de > serde:: de:: Visitor < ' de > for OptimizeVisitor {
903+ type Value = RustOptimize ;
904+
905+ fn expecting ( & self , formatter : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
906+ formatter. write_str ( r#"one of: 0, 1, 2, 3, "s", "z", true, false"# )
907+ }
908+
909+ fn visit_str < E > ( self , value : & str ) -> Result < Self :: Value , E >
910+ where
911+ E : serde:: de:: Error ,
912+ {
913+ if [ "s" , "z" ] . iter ( ) . find ( |x| * * x == value) . is_some ( ) {
914+ Ok ( RustOptimize :: String ( value. to_string ( ) ) )
915+ } else {
916+ Err ( format_optimize_error_msg ( value) ) . map_err ( serde:: de:: Error :: custom)
917+ }
918+ }
919+
920+ fn visit_i64 < E > ( self , value : i64 ) -> Result < Self :: Value , E >
921+ where
922+ E : serde:: de:: Error ,
923+ {
924+ if matches ! ( value, 0 ..=3 ) {
925+ Ok ( RustOptimize :: Int ( value as u8 ) )
926+ } else {
927+ Err ( format_optimize_error_msg ( value) ) . map_err ( serde:: de:: Error :: custom)
928+ }
929+ }
930+
931+ fn visit_bool < E > ( self , value : bool ) -> Result < Self :: Value , E >
932+ where
933+ E : serde:: de:: Error ,
934+ {
935+ Ok ( RustOptimize :: Bool ( value) )
901936 }
902937}
903938
939+ fn format_optimize_error_msg ( v : impl std:: fmt:: Display ) -> String {
940+ format ! (
941+ r#"unrecognized option for rust optimize: "{}", expected one of 0, 1, 2, 3, "s", "z", true, false"# ,
942+ v
943+ )
944+ }
945+
904946impl RustOptimize {
905947 pub ( crate ) fn is_release ( & self ) -> bool {
906- if let RustOptimize :: Bool ( true ) | RustOptimize :: String ( _) = & self { true } else { false }
948+ match & self {
949+ RustOptimize :: Bool ( true ) | RustOptimize :: String ( _) => true ,
950+ RustOptimize :: Int ( i) => * i > 0 ,
951+ RustOptimize :: Bool ( false ) => false ,
952+ }
907953 }
908954
909955 pub ( crate ) fn get_opt_level ( & self ) -> Option < String > {
910956 match & self {
911957 RustOptimize :: String ( s) => Some ( s. clone ( ) ) ,
958+ RustOptimize :: Int ( i) => Some ( i. to_string ( ) ) ,
912959 RustOptimize :: Bool ( _) => None ,
913960 }
914961 }
0 commit comments