@@ -764,7 +764,9 @@ unstable_cli_options!(
764764 dual_proc_macros: bool = ( "Build proc-macros for both the host and the target" ) ,
765765 features: Option <Vec <String >>,
766766 gc: bool = ( "Track cache usage and \" garbage collect\" unused files" ) ,
767+ #[ serde( deserialize_with = "deserialize_git_features" ) ]
767768 git: Option <GitFeatures > = ( "Enable support for shallow git fetch operations" ) ,
769+ #[ serde( deserialize_with = "deserialize_gitoxide_features" ) ]
768770 gitoxide: Option <GitoxideFeatures > = ( "Use gitoxide for the given git interactions, or all of them if no argument is given" ) ,
769771 host_config: bool = ( "Enable the `[host]` section in the .cargo/config.toml file" ) ,
770772 minimal_versions: bool = ( "Resolve minimal dependency versions instead of maximum" ) ,
@@ -874,7 +876,8 @@ where
874876 ) )
875877}
876878
877- #[ derive( Debug , Copy , Clone , Default , Deserialize ) ]
879+ #[ derive( Debug , Copy , Clone , Default , Deserialize , Ord , PartialOrd , Eq , PartialEq ) ]
880+ #[ serde( default ) ]
878881pub struct GitFeatures {
879882 /// When cloning the index, perform a shallow clone. Maintain shallowness upon subsequent fetches.
880883 pub shallow_index : bool ,
@@ -883,12 +886,71 @@ pub struct GitFeatures {
883886}
884887
885888impl GitFeatures {
886- fn all ( ) -> Self {
889+ pub fn all ( ) -> Self {
887890 GitFeatures {
888891 shallow_index : true ,
889892 shallow_deps : true ,
890893 }
891894 }
895+
896+ fn expecting ( ) -> String {
897+ let fields = vec ! [ "`shallow-index`" , "`shallow-deps`" ] ;
898+ format ! (
899+ "unstable 'git' only takes {} as valid inputs" ,
900+ fields. join( " and " )
901+ )
902+ }
903+ }
904+
905+ fn deserialize_git_features < ' de , D > ( deserializer : D ) -> Result < Option < GitFeatures > , D :: Error >
906+ where
907+ D : serde:: de:: Deserializer < ' de > ,
908+ {
909+ struct GitFeaturesVisitor ;
910+
911+ impl < ' de > serde:: de:: Visitor < ' de > for GitFeaturesVisitor {
912+ type Value = Option < GitFeatures > ;
913+
914+ fn expecting ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
915+ formatter. write_str ( & GitFeatures :: expecting ( ) )
916+ }
917+
918+ fn visit_bool < E > ( self , v : bool ) -> Result < Self :: Value , E >
919+ where
920+ E : serde:: de:: Error ,
921+ {
922+ if v {
923+ Ok ( Some ( GitFeatures :: all ( ) ) )
924+ } else {
925+ Ok ( None )
926+ }
927+ }
928+
929+ fn visit_str < E > ( self , s : & str ) -> Result < Self :: Value , E >
930+ where
931+ E : serde:: de:: Error ,
932+ {
933+ Ok ( parse_git ( s. split ( "," ) ) . map_err ( serde:: de:: Error :: custom) ?)
934+ }
935+
936+ fn visit_some < D > ( self , deserializer : D ) -> Result < Self :: Value , D :: Error >
937+ where
938+ D : serde:: de:: Deserializer < ' de > ,
939+ {
940+ let git = GitFeatures :: deserialize ( deserializer) ?;
941+ Ok ( Some ( git) )
942+ }
943+
944+ fn visit_map < V > ( self , map : V ) -> Result < Self :: Value , V :: Error >
945+ where
946+ V : serde:: de:: MapAccess < ' de > ,
947+ {
948+ let mvd = serde:: de:: value:: MapAccessDeserializer :: new ( map) ;
949+ Ok ( Some ( GitFeatures :: deserialize ( mvd) ?) )
950+ }
951+ }
952+
953+ deserializer. deserialize_any ( GitFeaturesVisitor )
892954}
893955
894956fn parse_git ( it : impl Iterator < Item = impl AsRef < str > > ) -> CargoResult < Option < GitFeatures > > {
@@ -903,16 +965,15 @@ fn parse_git(it: impl Iterator<Item = impl AsRef<str>>) -> CargoResult<Option<Gi
903965 "shallow-index" => * shallow_index = true ,
904966 "shallow-deps" => * shallow_deps = true ,
905967 _ => {
906- bail ! (
907- "unstable 'git' only takes 'shallow-index' and 'shallow-deps' as valid inputs"
908- )
968+ bail ! ( GitFeatures :: expecting( ) )
909969 }
910970 }
911971 }
912972 Ok ( Some ( out) )
913973}
914974
915- #[ derive( Debug , Copy , Clone , Default , Deserialize ) ]
975+ #[ derive( Debug , Copy , Clone , Default , Deserialize , Ord , PartialOrd , Eq , PartialEq ) ]
976+ #[ serde( default ) ]
916977pub struct GitoxideFeatures {
917978 /// All fetches are done with `gitoxide`, which includes git dependencies as well as the crates index.
918979 pub fetch : bool ,
@@ -926,7 +987,7 @@ pub struct GitoxideFeatures {
926987}
927988
928989impl GitoxideFeatures {
929- fn all ( ) -> Self {
990+ pub fn all ( ) -> Self {
930991 GitoxideFeatures {
931992 fetch : true ,
932993 checkout : true ,
@@ -943,6 +1004,67 @@ impl GitoxideFeatures {
9431004 internal_use_git2 : false ,
9441005 }
9451006 }
1007+
1008+ fn expecting ( ) -> String {
1009+ let fields = vec ! [ "`fetch`" , "`checkout`" , "`internal-use-git2`" ] ;
1010+ format ! (
1011+ "unstable 'gitoxide' only takes {} as valid inputs, for shallow fetches see `shallow-index,shallow-deps`" ,
1012+ fields. join( " and " )
1013+ )
1014+ }
1015+ }
1016+
1017+ fn deserialize_gitoxide_features < ' de , D > (
1018+ deserializer : D ,
1019+ ) -> Result < Option < GitoxideFeatures > , D :: Error >
1020+ where
1021+ D : serde:: de:: Deserializer < ' de > ,
1022+ {
1023+ struct GitoxideFeaturesVisitor ;
1024+
1025+ impl < ' de > serde:: de:: Visitor < ' de > for GitoxideFeaturesVisitor {
1026+ type Value = Option < GitoxideFeatures > ;
1027+
1028+ fn expecting ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1029+ formatter. write_str ( & GitoxideFeatures :: expecting ( ) )
1030+ }
1031+
1032+ fn visit_str < E > ( self , s : & str ) -> Result < Self :: Value , E >
1033+ where
1034+ E : serde:: de:: Error ,
1035+ {
1036+ Ok ( parse_gitoxide ( s. split ( "," ) ) . map_err ( serde:: de:: Error :: custom) ?)
1037+ }
1038+
1039+ fn visit_bool < E > ( self , v : bool ) -> Result < Self :: Value , E >
1040+ where
1041+ E : serde:: de:: Error ,
1042+ {
1043+ if v {
1044+ Ok ( Some ( GitoxideFeatures :: all ( ) ) )
1045+ } else {
1046+ Ok ( None )
1047+ }
1048+ }
1049+
1050+ fn visit_some < D > ( self , deserializer : D ) -> Result < Self :: Value , D :: Error >
1051+ where
1052+ D : serde:: de:: Deserializer < ' de > ,
1053+ {
1054+ let gitoxide = GitoxideFeatures :: deserialize ( deserializer) ?;
1055+ Ok ( Some ( gitoxide) )
1056+ }
1057+
1058+ fn visit_map < V > ( self , map : V ) -> Result < Self :: Value , V :: Error >
1059+ where
1060+ V : serde:: de:: MapAccess < ' de > ,
1061+ {
1062+ let mvd = serde:: de:: value:: MapAccessDeserializer :: new ( map) ;
1063+ Ok ( Some ( GitoxideFeatures :: deserialize ( mvd) ?) )
1064+ }
1065+ }
1066+
1067+ deserializer. deserialize_any ( GitoxideFeaturesVisitor )
9461068}
9471069
9481070fn parse_gitoxide (
@@ -961,7 +1083,7 @@ fn parse_gitoxide(
9611083 "checkout" => * checkout = true ,
9621084 "internal-use-git2" => * internal_use_git2 = true ,
9631085 _ => {
964- bail ! ( "unstable 'gitoxide' only takes `fetch` and 'checkout' as valid input, for shallow fetches see `-Zgit=shallow-index,shallow-deps`" )
1086+ bail ! ( GitoxideFeatures :: expecting ( ) )
9651087 }
9661088 }
9671089 }
0 commit comments