@@ -7,7 +7,7 @@ use cbork_cddl_parser::validate_cddl;
77#[ derive( serde:: Deserialize ) ]
88pub struct CddlDefitions ( HashMap < CddlType , CddlDef > ) ;
99
10- #[ derive( serde:: Deserialize , PartialEq , Eq , Hash ) ]
10+ #[ derive( Clone , serde:: Deserialize , PartialEq , Eq , Hash ) ]
1111pub struct CddlType ( String ) ;
1212
1313#[ derive( serde:: Deserialize ) ]
@@ -25,32 +25,57 @@ impl Display for CddlType {
2525 }
2626}
2727
28+ impl CddlDef {
29+ fn get_cddl_spec (
30+ & self ,
31+ cddl_type : & CddlType ,
32+ ) -> String {
33+ self . requires
34+ . iter ( )
35+ . enumerate ( )
36+ // replace `requires[i]` entries with the proper CDDL type names from the `requires`
37+ // list
38+ . fold ( format ! ( "{cddl_type}={}\n " , self . def) , |spec, ( i, req) | {
39+ spec. replace ( & format ! ( "requires[{i}]" ) , & req. 0 )
40+ } )
41+ }
42+ }
43+
2844impl CddlDefitions {
45+ fn find_cddl_def (
46+ & self ,
47+ cddl_type : & CddlType ,
48+ ) -> anyhow:: Result < & CddlDef > {
49+ self . 0 . get ( cddl_type) . ok_or ( anyhow:: anyhow!(
50+ "Cannot find a cddl defition for the {cddl_type}"
51+ ) )
52+ }
53+
2954 /// Returns a full CDDL specification schema.
3055 /// Performs
3156 pub fn get_cddl_spec (
3257 & self ,
3358 cddl_type : & CddlType ,
3459 ) -> anyhow:: Result < String > {
35- let def = self . 0 . get ( cddl_type) . ok_or ( anyhow:: anyhow!(
36- "Cannot find a cddl defition for the {cddl_type}"
37- ) ) ?;
60+ let def = self . find_cddl_def ( cddl_type) ?;
3861
39- let mut spec = def
40- . requires
41- . iter ( )
42- . enumerate ( )
43- // replace `requires[i]` entries with the proper CDDL type names from the `requires`
44- // list
45- . fold ( def. def . clone ( ) , |spec, ( i, req) | {
46- spec. replace ( & format ! ( "requires[{i}]" ) , & req. 0 )
47- } ) ;
62+ let spec = def. get_cddl_spec ( & cddl_type) ;
63+ let mut requires = def. requires . clone ( ) ;
4864
49- for req in & def. requires {
50- let req_spec = self . get_cddl_spec ( req) ?;
51- spec. push_str ( & req_spec) ;
65+ let mut imports = HashMap :: new ( ) ;
66+ while let Some ( req) = requires. pop ( ) {
67+ let req_def = self . find_cddl_def ( & req) ?;
68+ let req_spec = req_def. get_cddl_spec ( & req) ;
69+ if imports. insert ( req, req_spec) . is_none ( ) {
70+ requires. extend ( req_def. requires . clone ( ) ) ;
71+ }
5272 }
5373
74+ let mut spec = imports. values ( ) . fold ( spec, |mut spec, import_spec| {
75+ spec. push_str ( import_spec) ;
76+ spec
77+ } ) ;
78+
5479 validate_cddl ( & mut spec, & cbork_cddl_parser:: Extension :: CDDL ) ?;
5580 Ok ( spec)
5681 }
0 commit comments