Skip to content

Commit 8dcfe4d

Browse files
committed
wip
1 parent 2d4fa10 commit 8dcfe4d

File tree

7 files changed

+129
-6
lines changed

7 files changed

+129
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! 'required' field allowed values definition
22
33
/// "required" field definition
4-
#[derive(serde::Deserialize)]
4+
#[derive(serde::Deserialize, PartialEq, Eq)]
55
#[serde(rename_all = "lowercase")]
66
#[allow(clippy::missing_docs_in_private_items)]
77
pub enum IsRequired {

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub mod headers;
88
pub mod is_required;
99
pub mod metadata;
1010

11-
use std::collections::HashMap;
11+
use std::{collections::HashMap, fmt::Display};
1212

1313
use build_info as build_info_lib;
1414

@@ -27,6 +27,15 @@ pub struct CatalystSignedDocSpec {
2727
#[derive(serde::Deserialize, PartialEq, Eq, Hash)]
2828
pub struct DocumentName(String);
2929

30+
impl Display for DocumentName {
31+
fn fmt(
32+
&self,
33+
f: &mut std::fmt::Formatter<'_>,
34+
) -> std::fmt::Result {
35+
self.0.fmt(f)
36+
}
37+
}
38+
3039
impl DocumentName {
3140
/// returns document name
3241
#[must_use]

rust/signed_doc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ catalyst-types = { version = "0.0.6", git = "https://github.com/input-output-hk/
1515
cbork-utils = { version = "0.0.2", git = "https://github.com/input-output-hk/catalyst-libs.git", tag = "cbork-utils-v0.0.2" }
1616

1717
catalyst-signed-doc-macro = { version = "0.0.1", path = "../catalyst-signed-doc-macro" }
18+
catalyst-signed-doc-spec = { version = "0.1.3", path = "../catalyst-signed-doc-spec" }
1819

1920
anyhow = "1.0.95"
2021
serde = { version = "1.0.217", features = ["derive"] }

rust/signed_doc/src/validator/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ pub(crate) mod rules;
55

66
use std::{collections::HashMap, sync::LazyLock};
77

8-
use catalyst_signed_doc_macro;
98
use catalyst_types::catalyst_id::role_index::RoleId;
109
use rules::{
1110
ContentEncodingRule, ContentRule, ContentSchema, ContentTypeRule, IdRule, OriginalAuthorRule,
@@ -23,8 +22,6 @@ use crate::{
2322
CatalystSignedDocument, ContentEncoding, ContentType,
2423
};
2524

26-
catalyst_signed_doc_macro::catalyst_signed_documents_rules!();
27-
2825
/// A table representing a full set or validation rules per document id.
2926
static DOCUMENT_RULES: LazyLock<HashMap<DocType, Rules>> = LazyLock::new(document_rules_init);
3027

@@ -166,8 +163,11 @@ fn proposal_submission_action_rule() -> Rules {
166163
}
167164

168165
/// `DOCUMENT_RULES` initialization function
166+
#[allow(clippy::expect_used)]
169167
fn document_rules_init() -> HashMap<DocType, Rules> {
170-
let mut document_rules_map: HashMap<DocType, Rules> = documents_rules().collect();
168+
let mut document_rules_map: HashMap<DocType, Rules> = Rules::documents_rules()
169+
.expect("cannot fail to initialize validation rules")
170+
.collect();
171171

172172
// TODO: remove this redefinitions of the validation rules after
173173
// `catalyst_signed_documents_rules!` macro would be fully finished

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,33 @@ pub(crate) enum ContentTypeRule {
1616
}
1717

1818
impl ContentTypeRule {
19+
/// Generating `ContentTypeRule` from specs
20+
pub(crate) fn new(
21+
spec: &catalyst_signed_doc_spec::headers::content_type::ContentType
22+
) -> anyhow::Result<Self> {
23+
if let catalyst_signed_doc_spec::is_required::IsRequired::Excluded = spec.required {
24+
anyhow::ensure!(
25+
spec.value.is_none(),
26+
"'value' field must not exist when 'required' is 'excluded'"
27+
);
28+
return Ok(Self::NotSpecified);
29+
}
30+
31+
anyhow::ensure!(
32+
catalyst_signed_doc_spec::is_required::IsRequired::Optional == spec.required,
33+
"'content type' field cannot been optional"
34+
);
35+
36+
let value = spec
37+
.value
38+
.as_ref()
39+
.ok_or(anyhow::anyhow!("'content type' 'value' field must exist"))?;
40+
41+
Ok(Self::Specified {
42+
exp: value.parse()?,
43+
})
44+
}
45+
1946
/// Field validation rule
2047
#[allow(clippy::unused_async)]
2148
pub(crate) async fn check(

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! `ref` rule type impl.
22
3+
use std::collections::HashMap;
4+
35
use catalyst_types::problem_report::ProblemReport;
46

57
use crate::{
@@ -69,6 +71,43 @@ impl RefRule {
6971

7072
Ok(true)
7173
}
74+
75+
/// Generating `RefRule` from specs
76+
pub(crate) fn new(
77+
docs: &HashMap<catalyst_signed_doc_spec::DocumentName, catalyst_signed_doc_spec::DocSpec>,
78+
ref_spec: &catalyst_signed_doc_spec::metadata::doc_ref::Ref,
79+
) -> anyhow::Result<Self> {
80+
let optional = match ref_spec.required {
81+
catalyst_signed_doc_spec::is_required::IsRequired::Yes => false,
82+
catalyst_signed_doc_spec::is_required::IsRequired::Optional => true,
83+
catalyst_signed_doc_spec::is_required::IsRequired::Excluded => {
84+
return Ok(Self::NotSpecified);
85+
},
86+
};
87+
88+
anyhow::ensure!(!ref_spec.doc_type.is_empty(), "'type' field should exists and has at least one entry for the required 'ref' metadata definition");
89+
90+
let exp_ref_types = ref_spec.doc_type.iter().try_fold(
91+
Vec::new(),
92+
|mut res, doc_name| -> anyhow::Result<_> {
93+
let docs_spec = docs.get(doc_name).ok_or(anyhow::anyhow!(
94+
"cannot find a document definition {doc_name}"
95+
))?;
96+
res.push(docs_spec.doc_type.as_str().parse()?);
97+
Ok(res)
98+
},
99+
)?;
100+
101+
let multiple = ref_spec.multiple.ok_or(anyhow::anyhow!(
102+
"'multiple' field should exists for the required 'ref' metadata definition"
103+
))?;
104+
105+
Ok(Self::Specified {
106+
exp_ref_types,
107+
multiple,
108+
optional,
109+
})
110+
}
72111
}
73112

74113
/// Validate all the document references by the defined validation rules,

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,51 @@ impl Rules {
103103

104104
Ok(res)
105105
}
106+
107+
/// Returns an iterator with all defined Catalyst Signed Documents validation rules
108+
/// per corresponding document type based on the `signed_doc.json` file
109+
///
110+
/// # Errors:
111+
/// - `signed_doc.json` filed loading and JSON parsing errors.
112+
/// - `catalyst-signed-doc-spec` crate version doesn't align with the latest version
113+
/// of the `signed_doc.json`.
114+
pub(crate) fn documents_rules(
115+
) -> anyhow::Result<impl Iterator<Item = (crate::DocType, crate::validator::rules::Rules)>>
116+
{
117+
let spec = catalyst_signed_doc_spec::CatalystSignedDocSpec::load_signed_doc_spec()?;
118+
119+
let mut doc_rules = Vec::new();
120+
for (_, doc_spec) in &spec.docs {
121+
let rules = Self {
122+
id: IdRule,
123+
ver: VerRule,
124+
content_type: ContentTypeRule::new(&doc_spec.headers.content_type)?,
125+
content_encoding: ContentEncodingRule::NotSpecified,
126+
template: TemplateRule::NotSpecified,
127+
parameters: ParametersRule::NotSpecified,
128+
doc_ref: RefRule::new(&spec.docs, &doc_spec.metadata.doc_ref)?,
129+
reply: ReplyRule::NotSpecified,
130+
section: SectionRule::NotSpecified,
131+
content: ContentRule::Nil,
132+
kid: SignatureKidRule { exp: &[] },
133+
signature: SignatureRule { mutlisig: false },
134+
original_author: OriginalAuthorRule,
135+
};
136+
let doc_type = doc_spec.doc_type.parse()?;
137+
138+
doc_rules.push((doc_type, rules));
139+
}
140+
141+
Ok(doc_rules.into_iter())
142+
}
143+
}
144+
145+
#[cfg(test)]
146+
mod tests {
147+
use super::*;
148+
149+
#[test]
150+
fn rules_documents_rules_test() {
151+
let _unused = Rules::documents_rules().unwrap();
152+
}
106153
}

0 commit comments

Comments
 (0)