@@ -3,7 +3,6 @@ use std::{
3
3
path:: { Path , PathBuf } ,
4
4
} ;
5
5
6
- use gix:: Url ;
7
6
use nickel_lang_core:: {
8
7
cache:: normalize_rel_path,
9
8
eval:: cache:: CacheImpl ,
@@ -24,7 +23,15 @@ use crate::{
24
23
Dependency , Precise ,
25
24
} ;
26
25
27
- #[ derive( Clone , Debug ) ]
26
+ #[ derive( Clone , Debug , Deserialize ) ]
27
+ struct ManifestFileFormat {
28
+ pub name : Ident ,
29
+ pub version : semver:: Version ,
30
+ pub nickel_version : semver:: Version ,
31
+ pub dependencies : HashMap < Ident , Dependency > ,
32
+ }
33
+
34
+ #[ derive( Clone , Debug , PartialEq ) ]
28
35
pub struct ManifestFile {
29
36
// The directory containing the manifest file. Path deps are resolved relative to this.
30
37
// If `None`, path deps aren't allowed.
@@ -148,142 +155,23 @@ impl ManifestFile {
148
155
fn from_term ( rt : & RichTerm ) -> Result < Self , Error > {
149
156
// This is only ever called with terms that have passed the `std.package.Manifest`
150
157
// contract, so we can assume that they have the right fields.
151
- fn err ( s : & str ) -> Error {
152
- Error :: InternalManifestError { msg : s. to_owned ( ) }
153
- }
154
-
155
- let Term :: Record ( data) = rt. as_ref ( ) else {
156
- return Err ( err ( "manifest not a record" ) ) ;
157
- } ;
158
-
159
- // FIXME: yuck
160
- let name = data
161
- . fields
162
- . get ( & Ident :: new ( "name" ) )
163
- . ok_or_else ( || err ( "no name" ) ) ?
164
- . value
165
- . as_ref ( )
166
- . ok_or_else ( || err ( "name has no value" ) ) ?;
167
- let Term :: Str ( name) = name. as_ref ( ) else {
168
- return Err ( err ( "name not a string" ) ) ;
169
- } ;
170
-
171
- let version = data
172
- . fields
173
- . get ( & Ident :: new ( "version" ) )
174
- . ok_or_else ( || err ( "no version" ) ) ?
175
- . value
176
- . as_ref ( )
177
- . ok_or_else ( || err ( "version has no value" ) ) ?;
178
- let Term :: Str ( version) = version. as_ref ( ) else {
179
- return Err ( err ( "version not a string" ) ) ;
180
- } ;
181
-
182
- let nickel_version = data
183
- . fields
184
- . get ( & Ident :: new ( "nickel-version" ) )
185
- . ok_or_else ( || err ( "no nickel-version" ) ) ?
186
- . value
187
- . as_ref ( )
188
- . ok_or_else ( || err ( "nickel-version has no value" ) ) ?;
189
- let Term :: Str ( nickel_version) = nickel_version. as_ref ( ) else {
190
- return Err ( err ( "nickel-version not a string" ) ) ;
191
- } ;
192
-
193
- let deps = data
194
- . fields
195
- . get ( & Ident :: new ( "dependencies" ) )
196
- . ok_or_else ( || err ( "no dependencies" ) ) ?
197
- . value
198
- . as_ref ( )
199
- . ok_or_else ( || err ( "dependencies has no value" ) ) ?;
200
- let Term :: Record ( deps) = deps. as_ref ( ) else {
201
- return Err ( err ( "dependencies not a record" ) ) ;
202
- } ;
203
-
204
- let mut ret = Self {
205
- dependencies : HashMap :: new ( ) ,
158
+ let ManifestFileFormat {
159
+ name,
160
+ version,
161
+ nickel_version,
162
+ dependencies,
163
+ } = ManifestFileFormat :: deserialize ( rt. clone ( ) )
164
+ . map_err ( |e| Error :: InternalManifestError { msg : e. to_string ( ) } ) ?;
165
+ Ok ( Self {
206
166
parent_dir : None ,
207
- version : version. parse ( ) . map_err ( |_| err ( "invalid version" ) ) ?,
208
- nickel_version : nickel_version
209
- . parse ( )
210
- . map_err ( |_| err ( "invalid nickel version" ) ) ?,
211
- name : Ident :: new ( name) ,
212
- } ;
213
-
214
- for ( name, dep) in & deps. fields {
215
- let Term :: EnumVariant { tag, arg, .. } = dep
216
- . value
217
- . as_ref ( )
218
- . ok_or_else ( || err ( "dependency has no value" ) ) ?
219
- . as_ref ( )
220
- else {
221
- return Err ( err ( "dependency not an enum" ) ) ;
222
- } ;
223
-
224
- match tag. ident ( ) . label ( ) {
225
- "Git" => {
226
- let Term :: Record ( data) = arg. as_ref ( ) else {
227
- return Err ( err ( "payload wasn't a record" ) ) ;
228
- } ;
229
-
230
- let url = data
231
- . fields
232
- . get ( & Ident :: new ( "url" ) )
233
- . ok_or_else ( || err ( "no url" ) ) ?
234
- . value
235
- . as_ref ( )
236
- . ok_or_else ( || err ( "url has no value" ) ) ?;
237
- let Term :: Str ( url) = url. as_ref ( ) else {
238
- return Err ( err ( "url wasn't a string" ) ) ;
239
- } ;
240
-
241
- ret. dependencies . insert (
242
- name. ident ( ) ,
243
- Dependency :: Git {
244
- url : Url :: try_from ( url. to_string ( ) ) . map_err ( |e| Error :: InvalidUrl {
245
- url : url. to_string ( ) ,
246
- msg : e. to_string ( ) ,
247
- } ) ?,
248
- } ,
249
- ) ;
250
- }
251
- "Path" => {
252
- let Term :: Str ( path) = arg. as_ref ( ) else {
253
- return Err ( err ( "payload wasn't a string" ) ) ;
254
- } ;
255
-
256
- ret. dependencies . insert (
257
- name. ident ( ) ,
258
- Dependency :: Path {
259
- path : PathBuf :: from ( path. to_string ( ) ) ,
260
- } ,
261
- ) ;
262
- }
263
- "Index" => {
264
- let payload: IndexPayload = serde_json:: from_value (
265
- serde_json:: to_value ( arg. as_ref ( ) ) . map_err ( |_| err ( "bad payload" ) ) ?,
266
- )
267
- . map_err ( |_| err ( "bad payload" ) ) ?;
268
-
269
- let id: crate :: index:: Id = payload. name . parse ( ) . unwrap ( ) ;
270
- let version: semver:: VersionReq = payload. version . parse ( ) . unwrap ( ) ;
271
- ret. dependencies
272
- . insert ( name. ident ( ) , Dependency :: Index { id, version } ) ;
273
- }
274
- _ => return Err ( err ( "bad tag" ) ) ,
275
- }
276
- }
277
- Ok ( ret)
167
+ name,
168
+ version,
169
+ nickel_version,
170
+ dependencies,
171
+ } )
278
172
}
279
173
}
280
174
281
- #[ derive( Deserialize ) ]
282
- struct IndexPayload {
283
- name : String ,
284
- version : String ,
285
- }
286
-
287
175
#[ derive( Clone , Debug ) ]
288
176
pub struct RealizedDependency {
289
177
/// Either `Git` or `Path`.
@@ -408,3 +296,26 @@ impl Realization {
408
296
Ok ( id)
409
297
}
410
298
}
299
+
300
+ #[ cfg( test) ]
301
+ mod tests {
302
+ use super :: * ;
303
+
304
+ #[ test]
305
+ fn manifest ( ) {
306
+ let manifest = ManifestFile :: from_contents (
307
+ r#"{name = "foo", version = "1.0.0", nickel_version = "1.8.0"}"# . as_bytes ( ) ,
308
+ )
309
+ . unwrap ( ) ;
310
+ assert_eq ! (
311
+ manifest,
312
+ ManifestFile {
313
+ parent_dir: None ,
314
+ name: "foo" . into( ) ,
315
+ version: semver:: Version :: new( 1 , 0 , 0 ) ,
316
+ nickel_version: semver:: Version :: new( 1 , 8 , 0 ) ,
317
+ dependencies: HashMap :: default ( )
318
+ }
319
+ )
320
+ }
321
+ }
0 commit comments