@@ -38,7 +38,7 @@ pub const CANARY_EDITION: &str = concat!("0.", env!("CARGO_PKG_VERSION_MINOR"));
3838
3939/// Edition of the buffrs manifest
4040#[ derive( Debug , Clone , PartialEq , Eq , Deserialize , Serialize ) ]
41- #[ serde( into = "& str" , from = "& str" ) ]
41+ #[ serde( into = "Cow< str> " , from = "Cow< str> " ) ]
4242pub enum Edition {
4343 /// The canary edition of manifests
4444 ///
@@ -64,9 +64,22 @@ impl Edition {
6464 }
6565}
6666
67- impl From < & str > for Edition {
68- fn from ( value : & str ) -> Self {
69- match value {
67+ use std:: borrow:: Cow ;
68+
69+ impl < ' a > From < & ' a str > for Edition {
70+ fn from ( value : & ' a str ) -> Self {
71+ match & * value {
72+ self :: CANARY_EDITION => Self :: Canary ,
73+ "0.8" => Self :: Canary08 ,
74+ "0.7" => Self :: Canary07 ,
75+ _ => Self :: Unknown ,
76+ }
77+ }
78+ }
79+
80+ impl < ' a > From < Cow < ' a , str > > for Edition {
81+ fn from ( value : Cow < ' a , str > ) -> Self {
82+ match & * value {
7083 self :: CANARY_EDITION => Self :: Canary ,
7184 "0.8" => Self :: Canary08 ,
7285 "0.7" => Self :: Canary07 ,
@@ -86,13 +99,26 @@ impl From<Edition> for &'static str {
8699 }
87100}
88101
102+ impl From < Edition > for Cow < ' static , str > {
103+ fn from ( value : Edition ) -> Self {
104+ Cow :: Borrowed ( match value {
105+ Edition :: Canary => CANARY_EDITION ,
106+ Edition :: Canary08 => "0.8" ,
107+ Edition :: Canary07 => "0.7" ,
108+ Edition :: Unknown => "unknown" ,
109+ } )
110+ }
111+ }
112+
89113/// A buffrs manifest format used for serialization and deserialization.
90114///
91115/// This contains the exact structure of the `Proto.toml` and skips
92116/// empty fields.
93- #[ derive( Debug , Clone , PartialEq , Eq ) ]
117+ #[ derive( Debug , Clone , PartialEq , Eq , Serialize , Deserialize ) ]
118+ #[ serde( untagged) ]
94119enum RawManifest {
95120 Canary {
121+ edition : Edition ,
96122 package : Option < PackageManifest > ,
97123 dependencies : DependencyMap ,
98124 } ,
@@ -125,105 +151,44 @@ impl RawManifest {
125151 }
126152}
127153
128- mod serializer {
129- use super :: * ;
130- use serde:: { ser:: SerializeStruct , Serializer } ;
131-
132- impl Serialize for RawManifest {
133- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
134- where
135- S : Serializer ,
136- {
137- match * self {
138- RawManifest :: Canary {
139- ref package,
140- ref dependencies,
141- } => {
142- let mut s = serializer. serialize_struct ( "Canary" , 3 ) ?;
143- s. serialize_field ( "edition" , CANARY_EDITION ) ?;
144- s. serialize_field ( "package" , package) ?;
145- s. serialize_field ( "dependencies" , dependencies) ?;
146- s. end ( )
147- }
148- RawManifest :: Unknown {
149- ref package,
150- ref dependencies,
151- } => {
152- let mut s = serializer. serialize_struct ( "Unknown" , 2 ) ?;
153- s. serialize_field ( "package" , package) ?;
154- s. serialize_field ( "dependencies" , dependencies) ?;
155- s. end ( )
156- }
157- }
154+ #[ test]
155+ fn manifest ( ) {
156+ let mut dependencies = HashMap :: new ( ) ;
157+ dependencies. insert (
158+ PackageName :: new ( "foo" . to_string ( ) ) . unwrap ( ) ,
159+ LocalDependencyManifest {
160+ path : Path :: new ( "/foo/bar" ) . to_path_buf ( ) ,
158161 }
159- }
160- }
161-
162- mod deserializer {
163- use serde:: {
164- de:: { self , MapAccess , Visitor } ,
165- Deserializer ,
162+ . into ( ) ,
163+ ) ;
164+ let man = RawManifest :: Canary {
165+ edition : Edition :: from ( CANARY_EDITION ) ,
166+ package : None ,
167+ dependencies,
166168 } ;
169+ let x = toml:: to_string ( & man) . unwrap ( ) ;
170+ assert_eq ! (
171+ x,
172+ format!(
173+ "edition = \" {}\" \n \n [dependencies.foo]\n path = \" /foo/bar\" \n " ,
174+ CANARY_EDITION
175+ )
176+ ) ;
167177
168- use super :: * ;
169-
170- impl < ' de > Deserialize < ' de > for RawManifest {
171- fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
172- where
173- D : Deserializer < ' de > ,
174- {
175- static FIELDS : & [ & str ] = & [ "package" , "dependencies" ] ;
176-
177- struct ManifestVisitor ;
178-
179- impl < ' de > Visitor < ' de > for ManifestVisitor {
180- type Value = RawManifest ;
181-
182- fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
183- formatter. write_str ( "a buffrs manifest (`Proto.toml`)" )
184- }
185-
186- fn visit_map < V > ( self , mut map : V ) -> Result < RawManifest , V :: Error >
187- where
188- V : MapAccess < ' de > ,
189- {
190- let mut edition: Option < String > = None ;
191- let mut package: Option < PackageManifest > = None ;
192- let mut dependencies: Option < HashMap < PackageName , DependencyManifest > > = None ;
193-
194- while let Some ( key) = map. next_key :: < String > ( ) ? {
195- match key. as_str ( ) {
196- "package" => package = Some ( map. next_value ( ) ?) ,
197- "dependencies" => dependencies = Some ( map. next_value ( ) ?) ,
198- "edition" => edition = Some ( map. next_value ( ) ?) ,
199- _ => return Err ( de:: Error :: unknown_field ( & key, FIELDS ) ) ,
200- }
201- }
202-
203- let dependencies = dependencies. unwrap_or_default ( ) ;
204-
205- let Some ( edition) = edition else {
206- return Ok ( RawManifest :: Unknown {
207- package,
208- dependencies,
209- } ) ;
210- } ;
211-
212- match Edition :: from ( edition. as_str ( ) ) {
213- Edition :: Canary | Edition :: Canary08 | Edition :: Canary07 => Ok ( RawManifest :: Canary {
214- package,
215- dependencies,
216- } ) ,
217- Edition :: Unknown => Err ( de:: Error :: custom (
218- format ! ( "unsupported manifest edition, supported editions of {} are: {CANARY_EDITION}" , env!( "CARGO_PKG_VERSION" ) )
219- ) ) ,
220- }
221- }
222- }
178+ assert_eq ! ( toml:: from_str:: <RawManifest >( & x) . unwrap( ) , man) ;
179+ }
223180
224- deserializer. deserialize_map ( ManifestVisitor )
225- }
181+ #[ test]
182+ fn canary ( ) {
183+ let ed = Edition :: from ( CANARY_EDITION ) ;
184+ #[ derive( Debug , PartialEq , Serialize , Deserialize ) ]
185+ struct Ed {
186+ ed : Edition ,
226187 }
188+ let ed = Ed { ed } ;
189+ let x = toml:: to_string ( & ed) . unwrap ( ) ;
190+ assert_eq ! ( x, format!( "ed = \" {}\" \n " , CANARY_EDITION ) ) ;
191+ assert_eq ! ( toml:: from_str:: <Ed >( & x) . unwrap( ) , ed) ;
227192}
228193
229194impl From < Manifest > for RawManifest {
@@ -236,6 +201,7 @@ impl From<Manifest> for RawManifest {
236201
237202 match manifest. edition {
238203 Edition :: Canary | Edition :: Canary08 | Edition :: Canary07 => RawManifest :: Canary {
204+ edition : manifest. edition ,
239205 package : manifest. package ,
240206 dependencies,
241207 } ,
0 commit comments