Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rust/catalyst-signed-doc-macro/src/types_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ pub(crate) fn catalyst_signed_documents_types_consts_impl() -> anyhow::Result<To
let spec = CatalystSignedDocSpec::load_signed_doc_spec()?;

let mut consts_definitions = Vec::new();
for (doc_name, doc_spec) in spec.docs {
for (doc_name, doc_spec) in spec.docs.iter() {
if doc_spec.draft {
continue;
}
let const_type_name_ident = doc_name.ident();
let doc_name = doc_name.name();
let type_uuid = doc_spec.doc_type;
let type_uuid = &doc_spec.doc_type;

let const_definition = quote! {
#[doc = #doc_name ]
Expand Down
21 changes: 18 additions & 3 deletions rust/catalyst-signed-doc-spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,36 @@ pub mod headers;
pub mod is_required;
pub mod metadata;
pub mod payload;
pub mod signers;

use std::{collections::HashMap, fmt::Display};
use std::{collections::HashMap, fmt::Display, ops::Deref};

use build_info as build_info_lib;

use crate::{copyright::Copyright, headers::Headers, metadata::Metadata, payload::Payload};
use crate::{
copyright::Copyright, headers::Headers, metadata::Metadata, payload::Payload, signers::Signers,
};

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

/// Catalyst Signed Document spec representation struct
#[derive(serde::Deserialize)]
pub struct CatalystSignedDocSpec {
pub docs: HashMap<DocumentName, DocSpec>,
pub docs: DocSpecs,
copyright: Copyright,
}

#[derive(serde::Deserialize)]
pub struct DocSpecs(HashMap<DocumentName, DocSpec>);

impl Deref for DocSpecs {
type Target = HashMap<DocumentName, DocSpec>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

// A thin wrapper over the string document name values
#[derive(serde::Deserialize, PartialEq, Eq, Hash)]
pub struct DocumentName(String);
Expand Down Expand Up @@ -66,6 +80,7 @@ pub struct DocSpec {
pub doc_type: String,
pub headers: Headers,
pub metadata: Metadata,
pub signers: Signers,
pub payload: Payload,
}

Expand Down
4 changes: 4 additions & 0 deletions rust/catalyst-signed-doc-spec/src/metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! `metadata` field definition

pub mod doc_ref;
pub mod parameters;
pub mod reply;
pub mod template;

/// Document's metadata fields definition
Expand All @@ -10,4 +12,6 @@ pub struct Metadata {
pub template: template::Template,
#[serde(rename = "ref")]
pub doc_ref: doc_ref::Ref,
pub reply: reply::Reply,
pub parameters: parameters::Parameters,
}
17 changes: 17 additions & 0 deletions rust/catalyst-signed-doc-spec/src/metadata/parameters.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! `signed_doc.json` "parameters" field JSON definition

use std::ops::Deref;

use crate::metadata::doc_ref::Ref;

/// `signed_doc.json` "parameters" field JSON object
#[derive(serde::Deserialize)]
pub struct Parameters(pub Ref);

impl Deref for Parameters {
type Target = Ref;

fn deref(&self) -> &Self::Target {
&self.0
}
}
17 changes: 17 additions & 0 deletions rust/catalyst-signed-doc-spec/src/metadata/reply.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! `signed_doc.json` "reply" field JSON definition

use std::ops::Deref;

use crate::metadata::doc_ref::Ref;

/// `signed_doc.json` "reply" field JSON object
#[derive(serde::Deserialize)]
pub struct Reply(pub Ref);

impl Deref for Reply {
type Target = Ref;

fn deref(&self) -> &Self::Target {
&self.0
}
}
18 changes: 11 additions & 7 deletions rust/catalyst-signed-doc-spec/src/metadata/template.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
//! `signed_doc.json` "template" field JSON definition

use crate::{is_required::IsRequired, DocumentName};
use std::ops::Deref;

use crate::metadata::doc_ref::Ref;

/// `signed_doc.json` "template" field JSON object
#[derive(serde::Deserialize)]
#[allow(clippy::missing_docs_in_private_items, dead_code)]
pub struct Template {
pub required: IsRequired,
#[serde(rename = "type")]
pub doc_type: Option<DocumentName>,
pub multiple: Option<bool>,
pub struct Template(pub Ref);

impl Deref for Template {
type Target = Ref;

fn deref(&self) -> &Self::Target {
&self.0
}
}
10 changes: 10 additions & 0 deletions rust/catalyst-signed-doc-spec/src/signers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! 'signers' field definition

pub mod roles;

/// Document's 'signers' fields definition
#[derive(serde::Deserialize)]
#[allow(clippy::missing_docs_in_private_items)]
pub struct Signers {
pub roles: roles::Roles,
}
20 changes: 20 additions & 0 deletions rust/catalyst-signed-doc-spec/src/signers/roles.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! 'roles' field definition

/// Document's 'roles' fields definition
#[derive(serde::Deserialize)]
#[allow(clippy::missing_docs_in_private_items)]
pub struct Roles {
pub user: Vec<Role>,
}

/// Role definition
#[derive(serde::Deserialize)]
#[allow(clippy::missing_docs_in_private_items)]
pub enum Role {
/// Role 0 - A registered User / Voter - Base Role
Registered,
/// Registered for posting proposals
Proposer,
/// Registered as a rep for voting purposes.
Representative,
}
18 changes: 9 additions & 9 deletions rust/signed_doc/src/validator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ fn proposal_rule() -> Rules {
allowed_type: PROPOSAL_FORM_TEMPLATE.clone(),
},
parameters: ParametersRule::Specified {
exp_parameters_type: parameters.clone(),
allowed_type: parameters.clone(),
optional: false,
},
doc_ref: RefRule::NotSpecified,
reply: ReplyRule::NotSpecified,
section: SectionRule::NotSpecified,
content: ContentRule::NotNil,
kid: SignatureKidRule {
exp: &[RoleId::Proposer],
allowed_roles: vec![RoleId::Proposer],
},
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
Expand Down Expand Up @@ -88,22 +88,22 @@ fn proposal_comment_rule() -> Rules {
allowed_type: PROPOSAL_COMMENT_FORM_TEMPLATE.clone(),
},
doc_ref: RefRule::Specified {
exp_ref_types: vec![PROPOSAL.clone()],
allowed_type: vec![PROPOSAL.clone()],
multiple: false,
optional: false,
},
reply: ReplyRule::Specified {
exp_reply_type: PROPOSAL_COMMENT.clone(),
allowed_type: PROPOSAL_COMMENT.clone(),
optional: true,
},
section: SectionRule::NotSpecified,
parameters: ParametersRule::Specified {
exp_parameters_type: parameters.clone(),
allowed_type: parameters.clone(),
optional: false,
},
content: ContentRule::NotNil,
kid: SignatureKidRule {
exp: &[RoleId::Role0],
allowed_roles: vec![RoleId::Role0],
},
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
Expand Down Expand Up @@ -143,19 +143,19 @@ fn proposal_submission_action_rule() -> Rules {
},
template: TemplateRule::NotSpecified,
parameters: ParametersRule::Specified {
exp_parameters_type: parameters,
allowed_type: parameters,
optional: false,
},
doc_ref: RefRule::Specified {
exp_ref_types: vec![PROPOSAL.clone()],
allowed_type: vec![PROPOSAL.clone()],
multiple: false,
optional: false,
},
reply: ReplyRule::NotSpecified,
section: SectionRule::NotSpecified,
content: ContentRule::StaticSchema(ContentSchema::Json(proposal_action_json_schema)),
kid: SignatureKidRule {
exp: &[RoleId::Proposer],
allowed_roles: vec![RoleId::Proposer],
},
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
Expand Down
45 changes: 24 additions & 21 deletions rust/signed_doc/src/validator/rules/doc_ref.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! `ref` rule type impl.

use std::collections::HashMap;

use catalyst_signed_doc_spec::{is_required::IsRequired, metadata::doc_ref::Ref, DocSpecs};
use catalyst_types::problem_report::ProblemReport;

use crate::{
Expand All @@ -14,8 +13,8 @@ use crate::{
pub(crate) enum RefRule {
/// Is 'ref' specified
Specified {
/// expected `type` field of the referenced doc
exp_ref_types: Vec<DocType>,
/// allowed `type` field of the referenced doc
allowed_type: Vec<DocType>,
/// allows multiple document references or only one
multiple: bool,
/// optional flag for the `ref` field
Expand All @@ -27,20 +26,24 @@ pub(crate) enum RefRule {
impl RefRule {
/// Generating `RefRule` from specs
pub(crate) fn new(
docs: &HashMap<catalyst_signed_doc_spec::DocumentName, catalyst_signed_doc_spec::DocSpec>,
ref_spec: &catalyst_signed_doc_spec::metadata::doc_ref::Ref,
docs: &DocSpecs,
spec: &Ref,
) -> anyhow::Result<Self> {
let optional = match ref_spec.required {
catalyst_signed_doc_spec::is_required::IsRequired::Yes => false,
catalyst_signed_doc_spec::is_required::IsRequired::Optional => true,
catalyst_signed_doc_spec::is_required::IsRequired::Excluded => {
let optional = match spec.required {
IsRequired::Yes => false,
IsRequired::Optional => true,
IsRequired::Excluded => {
anyhow::ensure!(
spec.doc_type.is_empty() && spec.multiple.is_none(),
"'type' and 'multiple' fields could not been specified when 'required' is 'excluded' for 'ref' metadata definition"
);
return Ok(Self::NotSpecified);
},
};

anyhow::ensure!(!ref_spec.doc_type.is_empty(), "'type' field should exists and has at least one entry for the required 'ref' metadata definition");
anyhow::ensure!(!spec.doc_type.is_empty(), "'type' field should exists and has at least one entry for the required 'ref' metadata definition");

let exp_ref_types = ref_spec.doc_type.iter().try_fold(
let exp_ref_types = spec.doc_type.iter().try_fold(
Vec::new(),
|mut res, doc_name| -> anyhow::Result<_> {
let docs_spec = docs.get(doc_name).ok_or(anyhow::anyhow!(
Expand All @@ -51,12 +54,12 @@ impl RefRule {
},
)?;

let multiple = ref_spec.multiple.ok_or(anyhow::anyhow!(
let multiple = spec.multiple.ok_or(anyhow::anyhow!(
"'multiple' field should exists for the required 'ref' metadata definition"
))?;

Ok(Self::Specified {
exp_ref_types,
allowed_type: exp_ref_types,
multiple,
optional,
})
Expand All @@ -73,7 +76,7 @@ impl RefRule {
{
let context: &str = "Ref rule check";
if let Self::Specified {
exp_ref_types,
allowed_type: exp_ref_types,
multiple,
optional,
} = self
Expand Down Expand Up @@ -462,7 +465,7 @@ mod tests {
let doc = doc_gen(&exp_types, &mut provider);

let non_optional_res = RefRule::Specified {
exp_ref_types: exp_types.to_vec(),
allowed_type: exp_types.to_vec(),
multiple: true,
optional: false,
}
Expand All @@ -471,7 +474,7 @@ mod tests {
.unwrap();

let optional_res = RefRule::Specified {
exp_ref_types: exp_types.to_vec(),
allowed_type: exp_types.to_vec(),
multiple: true,
optional: true,
}
Expand Down Expand Up @@ -564,7 +567,7 @@ mod tests {
let doc = doc_gen(&exp_types, &mut provider);

let non_optional_res = RefRule::Specified {
exp_ref_types: exp_types.to_vec(),
allowed_type: exp_types.to_vec(),
multiple: false,
optional: false,
}
Expand All @@ -573,7 +576,7 @@ mod tests {
.unwrap();

let optional_res = RefRule::Specified {
exp_ref_types: exp_types.to_vec(),
allowed_type: exp_types.to_vec(),
multiple: false,
optional: true,
}
Expand All @@ -589,7 +592,7 @@ mod tests {
async fn ref_specified_optional_test() {
let provider = TestCatalystProvider::default();
let rule = RefRule::Specified {
exp_ref_types: vec![UuidV4::new().into()],
allowed_type: vec![UuidV4::new().into()],
multiple: true,
optional: true,
};
Expand All @@ -599,7 +602,7 @@ mod tests {

let provider = TestCatalystProvider::default();
let rule = RefRule::Specified {
exp_ref_types: vec![UuidV4::new().into()],
allowed_type: vec![UuidV4::new().into()],
multiple: true,
optional: false,
};
Expand Down
10 changes: 6 additions & 4 deletions rust/signed_doc/src/validator/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ impl Rules {
content_type: ContentTypeRule::new(&doc_spec.headers.content_type)?,
content_encoding: ContentEncodingRule::new(&doc_spec.headers.content_encoding)?,
template: TemplateRule::new(&spec.docs, &doc_spec.metadata.template)?,
parameters: ParametersRule::NotSpecified,
parameters: ParametersRule::new(&spec.docs, &doc_spec.metadata.parameters)?,
doc_ref: RefRule::new(&spec.docs, &doc_spec.metadata.doc_ref)?,
reply: ReplyRule::NotSpecified,
reply: ReplyRule::new(&spec.docs, &doc_spec.metadata.reply)?,
section: SectionRule::NotSpecified,
content: ContentRule::new(&doc_spec.payload)?,
kid: SignatureKidRule { exp: &[] },
kid: SignatureKidRule::new(&doc_spec.signers.roles),
signature: SignatureRule { mutlisig: false },
original_author: OriginalAuthorRule,
};
Expand All @@ -152,6 +152,8 @@ mod tests {

#[test]
fn rules_documents_rules_test() {
let _unused = Rules::documents_rules().unwrap();
for (doc_type, rules) in Rules::documents_rules().unwrap() {
println!("{doc_type}: {rules:?}");
}
}
}
Loading
Loading