@@ -6,6 +6,7 @@ use std::{
66
77use anyhow:: Context ;
88use async_trait:: async_trait;
9+ use serde:: de:: DeserializeOwned ;
910
1011use crate :: {
1112 Canister , Environment , LoadManifest , LoadPath , Network , Project ,
@@ -21,11 +22,11 @@ use crate::{
2122
2223#[ derive( Debug , thiserror:: Error ) ]
2324pub enum LoadPathError {
24- #[ error( "failed to read canister manifest" ) ]
25- Read ,
25+ #[ error( "failed to read manifest at {0} " ) ]
26+ Read ( String ) ,
2627
27- #[ error( "failed to deserialize canister manifest" ) ]
28- Deserialize ,
28+ #[ error( "failed to deserialize manifest at {0} " ) ]
29+ Deserialize ( String ) ,
2930
3031 #[ error( transparent) ]
3132 Unexpected ( #[ from] anyhow:: Error ) ,
@@ -34,14 +35,17 @@ pub enum LoadPathError {
3435pub struct PathLoader ;
3536
3637#[ async_trait]
37- impl LoadPath < ProjectManifest , LoadPathError > for PathLoader {
38- async fn load ( & self , path : & Path ) -> Result < ProjectManifest , LoadPathError > {
38+ impl < T > LoadPath < T , LoadPathError > for PathLoader
39+ where
40+ T : DeserializeOwned + Send + ' static ,
41+ {
42+ async fn load ( & self , path : & Path ) -> Result < T , LoadPathError > {
3943 // Read file
40- let mbs = read ( path) . context ( LoadPathError :: Read ) ?;
44+ let mbs = read ( path) . context ( LoadPathError :: Read ( path . to_string ( ) ) ) ?;
4145
42- // Load YAML
43- let m =
44- serde_yaml :: from_slice :: < ProjectManifest > ( & mbs ) . context ( LoadPathError :: Deserialize ) ?;
46+ // Deserialize YAML into any T
47+ let m = serde_yaml :: from_slice :: < T > ( & mbs )
48+ . context ( LoadPathError :: Deserialize ( path . to_string ( ) ) ) ?;
4549
4650 Ok ( m)
4751 }
@@ -216,7 +220,7 @@ impl LoadManifest<ProjectManifest, Project, LoadManifestError> for ManifestLoade
216220 let mut networks: HashMap < String , Network > = HashMap :: new ( ) ;
217221
218222 for i in & m. networks {
219- let ms = match i {
223+ let m = match i {
220224 Item :: Path ( path) => {
221225 let path = pdir. join ( path) ;
222226 if !path. exists ( ) || !path. is_file ( ) {
@@ -225,34 +229,62 @@ impl LoadManifest<ProjectManifest, Project, LoadManifestError> for ManifestLoade
225229 path : path. to_string ( ) ,
226230 } ) ;
227231 }
228- self . network . load ( path) . await . context ( LoadManifestError :: Failed { kind : "network" . to_string ( ) , path : path. to_string ( ) } ) ?
229-
230- } ,
231- Item :: Manifest ( ms) => ms,
232+ let loader = PathLoader ;
233+ loader
234+ . load ( & path)
235+ . await
236+ . context ( LoadManifestError :: Failed {
237+ kind : "network" . to_string ( ) ,
238+ path : path. to_string ( ) ,
239+ } ) ?
240+ }
241+ Item :: Manifest ( ms) => ms. clone ( ) ,
232242 } ;
233- //match networks.entry(m.name.to_owned()) {
234- // // Duplicate
235- // Entry::Occupied(e) => {
236- // return Err(LoadManifestError::Duplicate {
237- // kind: "network".to_string(),
238- // name: e.key().to_owned(),
239- // });
240- // }
241-
242- // // Ok
243- // Entry::Vacant(e) => {
244- // e.insert(Network {
245- // name: m.name.to_owned(),
246- // configuration: m.configuration.to_owned(),
247- // });
248- // }
249- //}
243+
244+ match networks. entry ( m. name . to_owned ( ) ) {
245+ // Duplicate
246+ Entry :: Occupied ( e) => {
247+ return Err ( LoadManifestError :: Duplicate {
248+ kind : "network" . to_string ( ) ,
249+ name : e. key ( ) . to_owned ( ) ,
250+ } ) ;
251+ }
252+
253+ // Ok
254+ Entry :: Vacant ( e) => {
255+ e. insert ( Network {
256+ name : m. name . to_owned ( ) ,
257+ configuration : m. configuration . to_owned ( ) ,
258+ } ) ;
259+ }
260+ }
250261 }
251262
252263 // Environments
253264 let mut environments: HashMap < String , Environment > = HashMap :: new ( ) ;
254265
255- for m in & m. environments {
266+ for i in & m. environments {
267+ let m = match i {
268+ Item :: Path ( path) => {
269+ let path = pdir. join ( path) ;
270+ if !path. exists ( ) || !path. is_file ( ) {
271+ return Err ( LoadManifestError :: NotFound {
272+ kind : "environment" . to_string ( ) ,
273+ path : path. to_string ( ) ,
274+ } ) ;
275+ }
276+ let loader = PathLoader ;
277+ loader
278+ . load ( & path)
279+ . await
280+ . context ( LoadManifestError :: Failed {
281+ kind : "environment" . to_string ( ) ,
282+ path : path. to_string ( ) ,
283+ } ) ?
284+ }
285+ Item :: Manifest ( ms) => ms. clone ( ) ,
286+ } ;
287+
256288 match environments. entry ( m. name . to_owned ( ) ) {
257289 // Duplicate
258290 Entry :: Occupied ( e) => {
0 commit comments