Skip to content

Commit d97fd39

Browse files
committed
wip
1 parent 48450f1 commit d97fd39

File tree

6 files changed

+89
-14
lines changed

6 files changed

+89
-14
lines changed

rust/catalyst-signed-doc-spec/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ workspace = true
1212

1313
[dependencies]
1414
catalyst-types = { version = "0.0.11", git = "https://github.com/input-output-hk/catalyst-libs.git", branch = "feat/json-schema-to-catalyst-types" }
15+
cbork-cddl-parser = { version = "0.0.3", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-cddl-parser/v0.0.3" }
1516

1617
serde_json = "1.0.142"
1718
anyhow = "1.0.99"
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//! 'cddlDefinitions' field definition
2+
3+
use std::{collections::HashMap, fmt::Display};
4+
5+
use cbork_cddl_parser::validate_cddl;
6+
7+
#[derive(serde::Deserialize)]
8+
pub struct CddlDefitions(HashMap<CddlType, CddlDef>);
9+
10+
#[derive(serde::Deserialize, PartialEq, Eq, Hash)]
11+
pub struct CddlType(String);
12+
13+
#[derive(serde::Deserialize)]
14+
struct CddlDef {
15+
def: String,
16+
requires: Vec<CddlType>,
17+
}
18+
19+
impl Display for CddlType {
20+
fn fmt(
21+
&self,
22+
f: &mut std::fmt::Formatter<'_>,
23+
) -> std::fmt::Result {
24+
self.0.fmt(f)
25+
}
26+
}
27+
28+
impl CddlDefitions {
29+
/// Returns a full CDDL specification schema.
30+
/// Performs
31+
pub fn get_cddl_spec(
32+
&self,
33+
cddl_type: &CddlType,
34+
) -> 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+
))?;
38+
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+
});
48+
49+
for req in &def.requires {
50+
let req_spec = self.get_cddl_spec(req)?;
51+
spec.push_str(&req_spec);
52+
}
53+
54+
validate_cddl(&mut spec, &cbork_cddl_parser::Extension::CDDL)?;
55+
Ok(spec)
56+
}
57+
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
#![allow(missing_docs, clippy::missing_docs_in_private_items)]
44

5-
pub mod copyright;
5+
pub mod cddl_definitions;
6+
mod copyright;
67
pub mod doc_types;
78
pub mod headers;
89
pub mod is_required;
@@ -15,16 +16,19 @@ use std::{collections::HashMap, fmt::Display, ops::Deref};
1516
use build_info as build_info_lib;
1617

1718
use crate::{
18-
copyright::Copyright, headers::Headers, metadata::Metadata, payload::Payload, signers::Signers,
19+
cddl_definitions::CddlDefitions, copyright::Copyright, headers::Headers, metadata::Metadata,
20+
payload::Payload, signers::Signers,
1921
};
2022

2123
build_info_lib::build_info!(pub(crate) fn build_info);
2224

2325
/// Catalyst Signed Document spec representation struct
2426
#[derive(serde::Deserialize)]
2527
pub struct CatalystSignedDocSpec {
26-
pub docs: DocSpecs,
28+
#[serde(rename = "cddlDefinitions")]
29+
pub cddl_definitions: CddlDefitions,
2730
copyright: Copyright,
31+
pub docs: DocSpecs,
2832
}
2933

3034
#[derive(serde::Deserialize)]

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
use catalyst_types::json_schema::JsonSchema;
44
use serde::Deserialize;
55

6+
use crate::cddl_definitions::CddlType;
7+
68
/// `signed_doc.json` "payload" field JSON object
79
#[derive(serde::Deserialize)]
810
#[allow(clippy::missing_docs_in_private_items)]
@@ -12,7 +14,7 @@ pub struct Payload {
1214
}
1315

1416
pub enum Schema {
15-
Cddl(String),
17+
Cddl(CddlType),
1618
Json(JsonSchema),
1719
}
1820

@@ -22,17 +24,17 @@ impl<'de> Deserialize<'de> for Schema {
2224
#[derive(serde::Deserialize)]
2325
#[serde(untagged)]
2426
pub enum SchemaSerde {
25-
Cddl(String),
27+
Cddl(CddlType),
2628
Json(serde_json::Value),
2729
}
2830

2931
match SchemaSerde::deserialize(deserializer)? {
30-
SchemaSerde::Json(schema) => {
31-
JsonSchema::try_from(&schema)
32+
SchemaSerde::Json(json) => {
33+
JsonSchema::try_from(&json)
3234
.map(|v| Self::Json(v))
3335
.map_err(|e| serde::de::Error::custom(e))
3436
},
35-
SchemaSerde::Cddl(schema) => Ok(Self::Cddl(schema)),
37+
SchemaSerde::Cddl(cddl_type) => Ok(Self::Cddl(cddl_type)),
3638
}
3739
}
3840
}

rust/signed_doc/src/validator/rules/content/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ mod tests;
55

66
use std::fmt::Debug;
77

8-
use catalyst_signed_doc_spec::payload::{Payload, Schema};
8+
use catalyst_signed_doc_spec::{
9+
cddl_definitions::CddlDefitions,
10+
payload::{Payload, Schema},
11+
};
912
use catalyst_types::json_schema::JsonSchema;
1013
use minicbor::Encode;
1114

@@ -45,7 +48,10 @@ pub(crate) enum ContentRule {
4548

4649
impl ContentRule {
4750
/// Generating `ContentRule` from specs
48-
pub(crate) fn new(spec: &Payload) -> anyhow::Result<Self> {
51+
pub(crate) fn new(
52+
cddl_def: &CddlDefitions,
53+
spec: &Payload,
54+
) -> anyhow::Result<Self> {
4955
if spec.nil {
5056
anyhow::ensure!(
5157
spec.schema.is_none(),
@@ -58,7 +64,11 @@ impl ContentRule {
5864
Some(Schema::Json(schema)) => {
5965
Ok(Self::StaticSchema(ContentSchema::Json(schema.clone())))
6066
},
61-
Some(Schema::Cddl(_)) => Ok(Self::StaticSchema(ContentSchema::Cddl)),
67+
Some(Schema::Cddl(cddl_type)) => {
68+
cddl_def
69+
.get_cddl_spec(cddl_type)
70+
.map(|_| Self::StaticSchema(ContentSchema::Cddl))
71+
},
6272
None => Ok(Self::NotNil),
6373
}
6474
}

rust/signed_doc/src/validator/rules/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! <https://input-output-hk.github.io/catalyst-libs/architecture/08_concepts/signed_doc/meta/>
33
44
use anyhow::Context;
5-
use catalyst_signed_doc_spec::{DocSpec, DocSpecs};
5+
use catalyst_signed_doc_spec::{cddl_definitions::CddlDefitions, DocSpec, DocSpecs};
66
use futures::FutureExt;
77

88
use crate::{
@@ -118,6 +118,7 @@ impl Rules {
118118

119119
/// Creating a `Rules` instance from the provided specs.
120120
fn new(
121+
cddl_defs: &CddlDefitions,
121122
all_docs_specs: &DocSpecs,
122123
doc_spec: &DocSpec,
123124
) -> anyhow::Result<Self> {
@@ -133,7 +134,7 @@ impl Rules {
133134
reply: ReplyRule::new(all_docs_specs, &doc_spec.metadata.reply)?,
134135
section: SectionRule::NotSpecified,
135136
collaborators: CollaboratorsRule::new(&doc_spec.metadata.collaborators),
136-
content: ContentRule::new(&doc_spec.payload)?,
137+
content: ContentRule::new(cddl_defs, &doc_spec.payload)?,
137138
kid: SignatureKidRule::new(&doc_spec.signers.roles)?,
138139
signature: SignatureRule,
139140
ownership: DocumentOwnershipRule::new(&doc_spec.signers.update, doc_spec)?,
@@ -157,7 +158,7 @@ impl Rules {
157158
continue;
158159
}
159160

160-
let rules = Self::new(&spec.docs, doc_spec)
161+
let rules = Self::new(&spec.cddl_definitions, &spec.docs, doc_spec)
161162
.context(format!("Fail to initializing document '{doc_name}'"))?;
162163
let doc_type = doc_spec.doc_type.parse()?;
163164

0 commit comments

Comments
 (0)