Skip to content

Commit f131bde

Browse files
committed
add ReplyRule initialisation
1 parent 7d708c2 commit f131bde

File tree

5 files changed

+65
-9
lines changed

5 files changed

+65
-9
lines changed

rust/catalyst-signed-doc-spec/src/metadata/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! `metadata` field definition
22
33
pub mod doc_ref;
4+
pub mod reply;
45
pub mod template;
56

67
/// Document's metadata fields definition
@@ -10,4 +11,5 @@ pub struct Metadata {
1011
pub template: template::Template,
1112
#[serde(rename = "ref")]
1213
pub doc_ref: doc_ref::Ref,
14+
pub reply: reply::Reply,
1315
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//! `signed_doc.json` "reply" field JSON definition
2+
3+
use std::ops::Deref;
4+
5+
use crate::metadata::doc_ref::Ref;
6+
7+
/// `signed_doc.json` "reply" field JSON object
8+
#[derive(serde::Deserialize)]
9+
pub struct Reply(pub Ref);
10+
11+
impl Deref for Reply {
12+
type Target = Ref;
13+
14+
fn deref(&self) -> &Self::Target {
15+
&self.0
16+
}
17+
}

rust/signed_doc/src/validator/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ fn proposal_comment_rule() -> Rules {
9393
optional: false,
9494
},
9595
reply: ReplyRule::Specified {
96-
exp_reply_type: PROPOSAL_COMMENT.clone(),
96+
allowed_type: PROPOSAL_COMMENT.clone(),
9797
optional: true,
9898
},
9999
section: SectionRule::NotSpecified,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl Rules {
130130
template: TemplateRule::new(&spec.docs, &doc_spec.metadata.template)?,
131131
parameters: ParametersRule::NotSpecified,
132132
doc_ref: RefRule::new(&spec.docs, &doc_spec.metadata.doc_ref)?,
133-
reply: ReplyRule::NotSpecified,
133+
reply: ReplyRule::new(&spec.docs, &doc_spec.metadata.reply)?,
134134
section: SectionRule::NotSpecified,
135135
content: ContentRule::new(&doc_spec.payload)?,
136136
kid: SignatureKidRule::new(&doc_spec.signers.roles),

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

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
//! `reply` rule type impl.
22
3+
use std::collections::HashMap;
4+
5+
use catalyst_signed_doc_spec::{
6+
is_required::IsRequired, metadata::reply::Reply, DocSpec, DocumentName,
7+
};
8+
39
use crate::{
410
providers::CatalystSignedDocumentProvider, validator::rules::doc_ref::doc_refs_check,
511
CatalystSignedDocument, DocType,
@@ -10,8 +16,8 @@ use crate::{
1016
pub(crate) enum ReplyRule {
1117
/// Is 'reply' specified
1218
Specified {
13-
/// expected `type` field of the replied doc
14-
exp_reply_type: DocType,
19+
/// allowed `type` field of the replied doc
20+
allowed_type: DocType,
1521
/// optional flag for the `ref` field
1622
optional: bool,
1723
},
@@ -20,6 +26,37 @@ pub(crate) enum ReplyRule {
2026
}
2127

2228
impl ReplyRule {
29+
/// Generating `RefRule` from specs
30+
pub(crate) fn new(
31+
docs: &HashMap<DocumentName, DocSpec>,
32+
spec: &Reply,
33+
) -> anyhow::Result<Self> {
34+
let optional = match spec.required {
35+
IsRequired::Yes => false,
36+
IsRequired::Optional => true,
37+
IsRequired::Excluded => {
38+
return Ok(Self::NotSpecified);
39+
},
40+
};
41+
42+
anyhow::ensure!(spec.doc_type.len() == 1, "'type' field should exists and has only one entry for the required 'reply' metadata definition");
43+
anyhow::ensure!(
44+
spec.multiple.is_some_and(|v| !v),
45+
"'multiple' field should be only set to false for the required 'reply' metadata definition"
46+
);
47+
48+
let doc_name = spec.doc_type.first().ok_or(anyhow::anyhow!("'type' field should exists and has only one entry for the required 'reply' metadata definition"))?;
49+
let docs_spec = docs.get(doc_name).ok_or(anyhow::anyhow!(
50+
"cannot find a document definition {doc_name}"
51+
))?;
52+
let allowed_type = docs_spec.doc_type.as_str().parse()?;
53+
54+
Ok(Self::Specified {
55+
allowed_type,
56+
optional,
57+
})
58+
}
59+
2360
/// Field validation rule
2461
pub(crate) async fn check<Provider>(
2562
&self,
@@ -31,7 +68,7 @@ impl ReplyRule {
3168
{
3269
let context: &str = "Reply rule check";
3370
if let Self::Specified {
34-
exp_reply_type,
71+
allowed_type: exp_reply_type,
3572
optional,
3673
} = self
3774
{
@@ -339,15 +376,15 @@ mod tests {
339376
let doc = doc_gen(exp_type.clone(), &mut provider);
340377

341378
let non_optional_res = ReplyRule::Specified {
342-
exp_reply_type: exp_type.clone(),
379+
allowed_type: exp_type.clone(),
343380
optional: false,
344381
}
345382
.check(&doc, &provider)
346383
.await
347384
.unwrap();
348385

349386
let optional_res = ReplyRule::Specified {
350-
exp_reply_type: exp_type.clone(),
387+
allowed_type: exp_type.clone(),
351388
optional: true,
352389
}
353390
.check(&doc, &provider)
@@ -362,7 +399,7 @@ mod tests {
362399
async fn reply_specified_optional_test() {
363400
let provider = TestCatalystProvider::default();
364401
let rule = ReplyRule::Specified {
365-
exp_reply_type: UuidV4::new().into(),
402+
allowed_type: UuidV4::new().into(),
366403
optional: true,
367404
};
368405

@@ -371,7 +408,7 @@ mod tests {
371408

372409
let provider = TestCatalystProvider::default();
373410
let rule = ReplyRule::Specified {
374-
exp_reply_type: UuidV4::new().into(),
411+
allowed_type: UuidV4::new().into(),
375412
optional: false,
376413
};
377414

0 commit comments

Comments
 (0)