Skip to content

Commit c206385

Browse files
authored
feat(rust/signed-doc): Initial catalyst_signed_documents_rules! macro implementation (#503)
* wip * wip * wip * wip * wip * fix spelling * fix spelling * fix clippy * wip * wip
1 parent fdce7e9 commit c206385

File tree

15 files changed

+144
-53
lines changed

15 files changed

+144
-53
lines changed

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

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
//! spec.
33
44
mod error;
5+
mod rules;
56
mod signed_doc_spec;
7+
mod types_consts;
68

7-
use proc_macro2::TokenStream;
8-
use quote::quote;
9+
use crate::error::process_error;
910

10-
use crate::{error::process_error, signed_doc_spec::CatalystSignedDocSpec};
11-
12-
/// Defines consts for all Catalyst Signed Documents types values
13-
/// e.g.
11+
/// Defines consts for all Catalyst Signed Documents types values, which are
12+
/// defined inside the `signed_doc.json` spec.
13+
///
14+
/// E.G.
1415
/// ```ignore
1516
/// pub const PROPOSAL: DocType = DocType::try_from_uuid(catalyst_types::uuid::uuid!(
1617
/// "7808d2ba-d511-40af-84e8-c0d1625fdfdc"
@@ -20,33 +21,21 @@ use crate::{error::process_error, signed_doc_spec::CatalystSignedDocSpec};
2021
pub fn catalyst_signed_documents_types_consts(
2122
_: proc_macro::TokenStream
2223
) -> proc_macro::TokenStream {
23-
catalyst_signed_documents_types_consts_impl()
24+
types_consts::catalyst_signed_documents_types_consts_impl()
2425
.unwrap_or_else(process_error)
2526
.into()
2627
}
2728

28-
/// `catalyst_signed_documents_types_consts` macro implementation
29-
fn catalyst_signed_documents_types_consts_impl() -> anyhow::Result<TokenStream> {
30-
let spec = CatalystSignedDocSpec::load_signed_doc_spec()?;
31-
32-
let mut consts_definitions = Vec::new();
33-
for (doc_name, doc_spec) in spec.docs {
34-
let const_type_name_ident = doc_name.ident();
35-
let doc_name = doc_name.name();
36-
let type_uuid = doc_spec.doc_type;
37-
38-
let const_definition = quote! {
39-
#[doc = #doc_name ]
40-
#[doc = "type constant definition"]
41-
pub const #const_type_name_ident: crate::DocType = match crate::DocType::try_from_uuid(catalyst_types::uuid::uuid!(#type_uuid)) {
42-
Ok(v) => v,
43-
Err(_) => panic!("invalid uuid v4 value"),
44-
};
45-
};
46-
consts_definitions.push(const_definition);
47-
}
48-
49-
Ok(quote! {
50-
#(#consts_definitions)*
51-
})
29+
/// Defines `documents_rules` function which will return a defined
30+
/// `catalyst_signed_doc::Rules` instances for each corresponding document type, which are
31+
/// defined inside the `signed_doc.json` spec.
32+
///
33+
/// ```ignore
34+
/// fn documents_rules() -> impl Iterator<Item = (DocType, Rules)>
35+
/// ```
36+
#[proc_macro]
37+
pub fn catalyst_signed_documents_rules(_: proc_macro::TokenStream) -> proc_macro::TokenStream {
38+
rules::catalyst_signed_documents_rules_impl()
39+
.unwrap_or_else(process_error)
40+
.into()
5241
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//! `catalyst_signed_documents_rules!` macro implementation
2+
3+
use proc_macro2::TokenStream;
4+
use quote::quote;
5+
6+
use crate::signed_doc_spec::CatalystSignedDocSpec;
7+
8+
/// `catalyst_signed_documents_rules` macro implementation
9+
pub(crate) fn catalyst_signed_documents_rules_impl() -> anyhow::Result<TokenStream> {
10+
let spec = CatalystSignedDocSpec::load_signed_doc_spec()?;
11+
12+
let mut rules_definitions = Vec::new();
13+
for (doc_name, _doc_spec) in spec.docs {
14+
let const_type_name_ident = doc_name.ident();
15+
16+
// TODO: implement a proper initialization for all specific validation rules
17+
let rules = quote! {
18+
crate::validator::rules::Rules {
19+
id: crate::validator::rules::IdRule,
20+
ver: crate::validator::rules::VerRule,
21+
content_type: crate::validator::rules::ContentTypeRule {
22+
exp: ContentType::Json,
23+
},
24+
content_encoding: crate::validator::rules::ContentEncodingRule {
25+
exp: ContentEncoding::Brotli,
26+
optional: false,
27+
},
28+
content: crate::validator::rules::ContentRule::NotSpecified,
29+
parameters: crate::validator::rules::ParametersRule::NotSpecified,
30+
doc_ref: crate::validator::rules::RefRule::NotSpecified,
31+
reply: crate::validator::rules::ReplyRule::NotSpecified,
32+
section: crate::validator::rules::SectionRule::NotSpecified,
33+
kid: crate::validator::rules::SignatureKidRule {
34+
exp: &[],
35+
},
36+
signature: crate::validator::rules::SignatureRule {
37+
mutlisig: false
38+
},
39+
}
40+
};
41+
42+
let rule_definition = quote! {
43+
(crate::doc_types::#const_type_name_ident, #rules),
44+
};
45+
rules_definitions.push(rule_definition);
46+
}
47+
48+
Ok(quote! {
49+
/// Returns an iterator with all defined Catalyst Signed Documents validation rules per corresponding document type
50+
fn documents_rules() -> impl Iterator<Item = (crate::DocType, crate::validator::rules::Rules)> {
51+
[ #(#rules_definitions)* ].into_iter()
52+
}
53+
})
54+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! `catalyst_signed_documents_types_consts!` macro implementation
2+
3+
use proc_macro2::TokenStream;
4+
use quote::quote;
5+
6+
use crate::signed_doc_spec::CatalystSignedDocSpec;
7+
8+
/// `catalyst_signed_documents_types_consts` macro implementation
9+
pub(crate) fn catalyst_signed_documents_types_consts_impl() -> anyhow::Result<TokenStream> {
10+
let spec = CatalystSignedDocSpec::load_signed_doc_spec()?;
11+
12+
let mut consts_definitions = Vec::new();
13+
for (doc_name, doc_spec) in spec.docs {
14+
let const_type_name_ident = doc_name.ident();
15+
let doc_name = doc_name.name();
16+
let type_uuid = doc_spec.doc_type;
17+
18+
let const_definition = quote! {
19+
#[doc = #doc_name ]
20+
#[doc = "type constant definition"]
21+
pub const #const_type_name_ident: crate::DocType = match crate::DocType::try_from_uuid(catalyst_types::uuid::uuid!(#type_uuid)) {
22+
Ok(v) => v,
23+
Err(_) => panic!("invalid uuid v4 value"),
24+
};
25+
};
26+
consts_definitions.push(const_definition);
27+
}
28+
29+
Ok(quote! {
30+
#(#consts_definitions)*
31+
})
32+
}

rust/signed_doc/src/validator/mod.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
pub(crate) mod json_schema;
44
pub(crate) mod rules;
55

6-
use std::{
7-
collections::HashMap,
8-
sync::{Arc, LazyLock},
9-
};
6+
use std::{collections::HashMap, sync::LazyLock};
107

8+
use catalyst_signed_doc_macro;
119
use catalyst_types::catalyst_id::role_index::RoleId;
1210
use rules::{
1311
ContentEncodingRule, ContentRule, ContentSchema, ContentTypeRule, IdRule, ParametersRule,
@@ -25,8 +23,10 @@ use crate::{
2523
CatalystSignedDocument, ContentEncoding, ContentType,
2624
};
2725

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

3131
/// Proposal
3232
/// Require field: type, id, ver, template, parameters
@@ -158,18 +158,16 @@ fn proposal_submission_action_rule() -> Rules {
158158
}
159159

160160
/// `DOCUMENT_RULES` initialization function
161-
fn document_rules_init() -> HashMap<DocType, Arc<Rules>> {
162-
let mut document_rules_map = HashMap::new();
163-
164-
let proposal_rules = Arc::new(proposal_rule());
165-
let comment_rules = Arc::new(proposal_comment_rule());
166-
let action_rules = Arc::new(proposal_submission_action_rule());
161+
fn document_rules_init() -> HashMap<DocType, Rules> {
162+
let mut document_rules_map: HashMap<DocType, Rules> = documents_rules().collect();
167163

168-
document_rules_map.insert(PROPOSAL.clone(), Arc::clone(&proposal_rules));
169-
document_rules_map.insert(PROPOSAL_COMMENT.clone(), Arc::clone(&comment_rules));
164+
// TODO: remove this redefinitions of the validation rules after
165+
// `catalyst_signed_documents_rules!` macro would be fully finished
166+
document_rules_map.insert(PROPOSAL.clone(), proposal_rule());
167+
document_rules_map.insert(PROPOSAL_COMMENT.clone(), proposal_comment_rule());
170168
document_rules_map.insert(
171169
PROPOSAL_SUBMISSION_ACTION.clone(),
172-
Arc::clone(&action_rules),
170+
proposal_submission_action_rule(),
173171
);
174172

175173
document_rules_map

rust/signed_doc/src/validator/rules/template.rs renamed to rust/signed_doc/src/validator/rules/content.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! `template` rule type impl.
22
3-
use std::fmt::Write;
3+
use std::fmt::{Debug, Write};
44

55
use crate::{
66
metadata::ContentType,
@@ -16,7 +16,19 @@ pub(crate) enum ContentSchema {
1616
Json(json_schema::JsonSchema),
1717
}
1818

19+
impl Debug for ContentSchema {
20+
fn fmt(
21+
&self,
22+
f: &mut std::fmt::Formatter<'_>,
23+
) -> std::fmt::Result {
24+
match self {
25+
Self::Json(_) => writeln!(f, "JsonSchema"),
26+
}
27+
}
28+
}
29+
1930
/// Document's content validation rule
31+
#[derive(Debug)]
2032
pub(crate) enum ContentRule {
2133
/// Based on the 'template' field and loaded corresponding template document
2234
Templated {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use crate::{metadata::ContentEncoding, CatalystSignedDocument};
44

55
/// `content-encoding` field validation rule
6+
#[derive(Debug)]
67
pub(crate) struct ContentEncodingRule {
78
/// expected `content-encoding` field
89
pub(crate) exp: ContentEncoding,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::{metadata::ContentType, CatalystSignedDocument};
44

55
/// `content-type` field validation rule
6-
#[derive(Clone, Debug, PartialEq)]
6+
#[derive(Debug)]
77
pub(crate) struct ContentTypeRule {
88
/// expected `content-type` field
99
pub(crate) exp: ContentType,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
};
99

1010
/// `ref` field validation rule
11-
#[derive(Clone, Debug, PartialEq)]
11+
#[derive(Debug)]
1212
pub(crate) enum RefRule {
1313
/// Is 'ref' specified
1414
Specified {
@@ -52,7 +52,7 @@ impl RefRule {
5252
return Ok(false);
5353
}
5454
}
55-
if &Self::NotSpecified == self {
55+
if let Self::NotSpecified = self {
5656
if let Some(doc_ref) = doc.doc_meta().doc_ref() {
5757
doc.report().unknown_field(
5858
"ref",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use anyhow::Context;
77
use crate::{providers::CatalystSignedDocumentProvider, CatalystSignedDocument};
88

99
/// Signed Document `id` field validation rule
10+
#[derive(Debug)]
1011
pub(crate) struct IdRule;
1112

1213
impl IdRule {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
CatalystSignedDocument,
99
};
1010

11+
mod content;
1112
mod content_encoding;
1213
mod content_type;
1314
mod doc_ref;
@@ -17,9 +18,9 @@ mod reply;
1718
mod section;
1819
mod signature;
1920
mod signature_kid;
20-
mod template;
2121
mod ver;
2222

23+
pub(crate) use content::{ContentRule, ContentSchema};
2324
pub(crate) use content_encoding::ContentEncodingRule;
2425
pub(crate) use content_type::ContentTypeRule;
2526
pub(crate) use doc_ref::RefRule;
@@ -29,10 +30,10 @@ pub(crate) use reply::ReplyRule;
2930
pub(crate) use section::SectionRule;
3031
pub(crate) use signature::SignatureRule;
3132
pub(crate) use signature_kid::SignatureKidRule;
32-
pub(crate) use template::{ContentRule, ContentSchema};
3333
pub(crate) use ver::VerRule;
3434

3535
/// Struct represented a full collection of rules for all fields
36+
#[derive(Debug)]
3637
pub(crate) struct Rules {
3738
/// 'id' field validation rule
3839
pub(crate) id: IdRule,

0 commit comments

Comments
 (0)