Skip to content

Commit 6cd7cae

Browse files
committed
wip
1 parent 81ba5cf commit 6cd7cae

File tree

1 file changed

+41
-16
lines changed

1 file changed

+41
-16
lines changed

rust/catalyst-signed-doc-spec/src/cddl_definitions.rs

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use cbork_cddl_parser::validate_cddl;
77
#[derive(serde::Deserialize)]
88
pub struct CddlDefitions(HashMap<CddlType, CddlDef>);
99

10-
#[derive(serde::Deserialize, PartialEq, Eq, Hash)]
10+
#[derive(Clone, serde::Deserialize, PartialEq, Eq, Hash)]
1111
pub 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+
2844
impl 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

Comments
 (0)