Skip to content

Commit f9ec1fc

Browse files
committed
replace trait with Fn
1 parent d173bf4 commit f9ec1fc

File tree

4 files changed

+80
-62
lines changed

4 files changed

+80
-62
lines changed

rust/signed_doc/src/doc_types/comment_document.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
doc_types::{COMMENT_TEMPLATE_UUID_TYPE, PROPOSAL_DOCUMENT_UUID_TYPE},
88
error::CatalystSignedDocError,
99
metadata::{ContentEncoding, ContentType},
10-
validator::{utils::validate_provided_doc, ValidationDataProvider, Validator},
10+
validator::{utils::validate_provided_doc, StatefullValidation, StatelessValidation},
1111
CatalystSignedDocument, DocumentRef,
1212
};
1313

@@ -30,9 +30,7 @@ pub struct CommentDocument {
3030
content: serde_json::Value,
3131
}
3232

33-
impl Validator for CommentDocument {
34-
const STATEFULL_RULES: &[crate::validator::StatefullRule<Self>] =
35-
&[template_full_check, ref_full_check, reply_full_check];
33+
impl StatelessValidation for CommentDocument {
3634
const STATELESS_RULES: &[crate::validator::StatelessRule] = &[
3735
type_check,
3836
content_type_check,
@@ -42,6 +40,13 @@ impl Validator for CommentDocument {
4240
];
4341
}
4442

43+
impl<DocProvider> StatefullValidation<DocProvider> for CommentDocument
44+
where DocProvider: 'static + Fn(&DocumentRef) -> Option<CatalystSignedDocument>
45+
{
46+
const STATEFULL_RULES: &[crate::validator::StatefullRule<Self, DocProvider>] =
47+
&[template_full_check, ref_full_check, reply_full_check];
48+
}
49+
4550
/// `type` field validation
4651
fn type_check(doc: &CatalystSignedDocument, report: &ProblemReport) -> bool {
4752
if doc.doc_type().uuid() != COMMENT_DOCUMENT_UUID_TYPE {
@@ -111,9 +116,10 @@ fn reply_check(doc: &CatalystSignedDocument, report: &ProblemReport) -> bool {
111116
}
112117

113118
/// `template` statefull validation
114-
fn template_full_check(
115-
doc: &CommentDocument, provider: &dyn ValidationDataProvider, report: &ProblemReport,
116-
) -> bool {
119+
fn template_full_check<DocProvider>(
120+
doc: &CommentDocument, provider: &DocProvider, report: &ProblemReport,
121+
) -> bool
122+
where DocProvider: Fn(&DocumentRef) -> Option<CatalystSignedDocument> {
117123
let template_validator = |template_doc: CatalystSignedDocument| {
118124
if template_doc.doc_type().uuid() != COMMENT_TEMPLATE_UUID_TYPE {
119125
report.invalid_value(
@@ -164,9 +170,10 @@ fn template_full_check(
164170
}
165171

166172
/// `ref` statefull validation
167-
fn ref_full_check(
168-
doc: &CommentDocument, provider: &dyn ValidationDataProvider, report: &ProblemReport,
169-
) -> bool {
173+
fn ref_full_check<DocProvider>(
174+
doc: &CommentDocument, provider: &DocProvider, report: &ProblemReport,
175+
) -> bool
176+
where DocProvider: Fn(&DocumentRef) -> Option<CatalystSignedDocument> {
170177
let ref_validator = |proposal_doc: CatalystSignedDocument| -> bool {
171178
if proposal_doc.doc_type().uuid() != PROPOSAL_DOCUMENT_UUID_TYPE {
172179
report.invalid_value(
@@ -183,9 +190,10 @@ fn ref_full_check(
183190
}
184191

185192
/// `reply` statefull validation
186-
fn reply_full_check(
187-
doc: &CommentDocument, provider: &dyn ValidationDataProvider, report: &ProblemReport,
188-
) -> bool {
193+
fn reply_full_check<DocProvider>(
194+
doc: &CommentDocument, provider: &DocProvider, report: &ProblemReport,
195+
) -> bool
196+
where DocProvider: Fn(&DocumentRef) -> Option<CatalystSignedDocument> {
189197
if let Some(reply) = &doc.reply {
190198
let reply_validator = |comment_doc: CatalystSignedDocument| -> bool {
191199
if comment_doc.doc_type().uuid() != COMMENT_DOCUMENT_UUID_TYPE {
@@ -225,7 +233,7 @@ impl CommentDocument {
225233
pub(crate) fn from_signed_doc(
226234
doc: &CatalystSignedDocument, report: &ProblemReport,
227235
) -> anyhow::Result<Self> {
228-
if Self::stateless_validation(doc, report) {
236+
if <Self as StatelessValidation>::validate(doc, report) {
229237
anyhow::bail!("Failed to build `CommentDocument` from `CatalystSignedDoc`");
230238
}
231239

rust/signed_doc/src/doc_types/proposal_document.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use crate::{
88
error::CatalystSignedDocError,
99
metadata::{ContentEncoding, ContentType},
1010
validator::{
11-
utils::validate_provided_doc, StatefullRule, StatelessRule, ValidationDataProvider,
12-
Validator,
11+
utils::validate_provided_doc, StatefullRule, StatefullValidation, StatelessRule,
12+
StatelessValidation,
1313
},
1414
CatalystSignedDocument, DocumentRef,
1515
};
@@ -28,8 +28,7 @@ pub struct ProposalDocument {
2828
content: serde_json::Value,
2929
}
3030

31-
impl Validator for ProposalDocument {
32-
const STATEFULL_RULES: &[StatefullRule<Self>] = &[template_full_check, category_full_check];
31+
impl StatelessValidation for ProposalDocument {
3332
const STATELESS_RULES: &[StatelessRule] = &[
3433
type_check,
3534
content_type_check,
@@ -38,6 +37,13 @@ impl Validator for ProposalDocument {
3837
];
3938
}
4039

40+
impl<DocProvider> StatefullValidation<DocProvider> for ProposalDocument
41+
where DocProvider: 'static + Fn(&DocumentRef) -> Option<CatalystSignedDocument>
42+
{
43+
const STATEFULL_RULES: &[StatefullRule<Self, DocProvider>] =
44+
&[template_full_check, category_full_check];
45+
}
46+
4147
/// `type` field validation
4248
fn type_check(doc: &CatalystSignedDocument, report: &ProblemReport) -> bool {
4349
if doc.doc_type().uuid() != PROPOSAL_DOCUMENT_UUID_TYPE {
@@ -98,9 +104,10 @@ fn template_check(doc: &CatalystSignedDocument, report: &ProblemReport) -> bool
98104
}
99105

100106
/// `template` statefull validation
101-
fn template_full_check(
102-
doc: &ProposalDocument, provider: &dyn ValidationDataProvider, report: &ProblemReport,
103-
) -> bool {
107+
fn template_full_check<DocProvider>(
108+
doc: &ProposalDocument, provider: &DocProvider, report: &ProblemReport,
109+
) -> bool
110+
where DocProvider: Fn(&DocumentRef) -> Option<CatalystSignedDocument> {
104111
let template_validator = |template_doc: CatalystSignedDocument| {
105112
if template_doc.doc_type().uuid() != PROPOSAL_TEMPLATE_UUID_TYPE {
106113
report.invalid_value(
@@ -150,9 +157,10 @@ fn template_full_check(
150157
}
151158

152159
/// `category_id` statefull validation
153-
fn category_full_check(
154-
doc: &ProposalDocument, provider: &dyn ValidationDataProvider, report: &ProblemReport,
155-
) -> bool {
160+
fn category_full_check<DocProvider>(
161+
doc: &ProposalDocument, provider: &DocProvider, report: &ProblemReport,
162+
) -> bool
163+
where DocProvider: Fn(&DocumentRef) -> Option<CatalystSignedDocument> {
156164
if let Some(category) = &doc.category {
157165
let category_validator = |category_doc: CatalystSignedDocument| -> bool {
158166
if category_doc.doc_type().uuid() != CATEGORY_DOCUMENT_UUID_TYPE {
@@ -177,7 +185,7 @@ impl ProposalDocument {
177185
pub(crate) fn from_signed_doc(
178186
doc: &CatalystSignedDocument, report: &ProblemReport,
179187
) -> anyhow::Result<Self> {
180-
if Self::stateless_validation(doc, report) {
188+
if <Self as StatelessValidation>::validate(doc, report) {
181189
anyhow::bail!("Failed to build `ProposalDocument` from `CatalystSignedDoc`");
182190
}
183191

rust/signed_doc/src/validator/mod.rs

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,52 @@
22
33
pub(crate) mod utils;
44

5-
use catalyst_types::{id_uri::IdUri, problem_report::ProblemReport};
6-
use rbac_registration::cardano::cip509::SimplePublicKeyType;
5+
use catalyst_types::problem_report::ProblemReport;
76

87
use crate::{
98
doc_types::{CommentDocument, DocumentType, ProposalDocument},
109
error::CatalystSignedDocError,
1110
CatalystSignedDocument, DocumentRef,
1211
};
1312

14-
/// Trait for getting a necessary data needed during the validation process.
15-
pub trait ValidationDataProvider {
16-
/// Get public keys
17-
fn get_public_key(&self, kid: &IdUri) -> Option<SimplePublicKeyType>;
18-
/// Get signed document by document reference
19-
fn get_doc(&self, doc_ref: &DocumentRef) -> Option<CatalystSignedDocument>;
20-
}
21-
2213
/// Stateless validation function rule type
2314
pub(crate) type StatelessRule = fn(&CatalystSignedDocument, &ProblemReport) -> bool;
2415
/// Statefull validation function rule type
25-
pub(crate) type StatefullRule<T> = fn(&T, &dyn ValidationDataProvider, &ProblemReport) -> bool;
16+
pub(crate) type StatefullRule<DocType, DocProvider> =
17+
fn(&DocType, &DocProvider, &ProblemReport) -> bool;
18+
19+
/// Trait for defining a statefull validation rules.
20+
pub trait StatefullValidation<DocProvider>
21+
where
22+
Self: 'static,
23+
DocProvider: 'static + Fn(&DocumentRef) -> Option<CatalystSignedDocument>,
24+
{
25+
/// Statefull validation rules
26+
const STATEFULL_RULES: &[StatefullRule<Self, DocProvider>];
2627

27-
/// Trait for defining a validation rules.
28-
pub trait Validator
28+
/// Perform a statefull validation, collecting a problem report
29+
fn validate(&self, provider: &DocProvider, report: &ProblemReport) -> bool {
30+
Self::STATEFULL_RULES
31+
.iter()
32+
.map(|rule| rule(self, provider, report))
33+
.all(|res| res)
34+
}
35+
}
36+
37+
/// Trait for defining a stateless validation rules.
38+
pub trait StatelessValidation
2939
where Self: 'static
3040
{
3141
/// Stateless validation rules
3242
const STATELESS_RULES: &[StatelessRule];
33-
/// Statefull validation rules
34-
const STATEFULL_RULES: &[StatefullRule<Self>];
3543

3644
/// Perform a stateless validation, collecting a problem report
37-
fn stateless_validation(doc: &CatalystSignedDocument, report: &ProblemReport) -> bool {
45+
fn validate(doc: &CatalystSignedDocument, report: &ProblemReport) -> bool {
3846
Self::STATELESS_RULES
3947
.iter()
4048
.map(|rule| rule(doc, report))
4149
.all(|res| res)
4250
}
43-
44-
/// Perform a statefull validation, collecting a problem report
45-
fn statefull_validation(
46-
&self, provider: &impl ValidationDataProvider, report: &ProblemReport,
47-
) -> bool {
48-
Self::STATEFULL_RULES
49-
.iter()
50-
.map(|rule| rule(self, provider, report))
51-
.all(|res| res)
52-
}
5351
}
5452

5553
/// A comprehensive validation of the `CatalystSignedDocument`,
@@ -58,9 +56,10 @@ where Self: 'static
5856
/// # Errors
5957
///
6058
/// Returns a report of validation failures and the source error.
61-
pub fn validate(
62-
doc: &CatalystSignedDocument, doc_provider: &impl ValidationDataProvider,
63-
) -> Result<(), CatalystSignedDocError> {
59+
pub fn validate<DocProvider>(
60+
doc: &CatalystSignedDocument, provider: &DocProvider,
61+
) -> Result<(), CatalystSignedDocError>
62+
where DocProvider: 'static + Fn(&DocumentRef) -> Option<CatalystSignedDocument> {
6463
let report = ProblemReport::new("Catalyst Signed Document Validation");
6564

6665
let doc_type: DocumentType = match doc.doc_type().try_into() {
@@ -83,13 +82,13 @@ pub fn validate(
8382
match doc_type {
8483
DocumentType::ProposalDocument => {
8584
if let Ok(proposal_doc) = ProposalDocument::from_signed_doc(doc, &report) {
86-
proposal_doc.statefull_validation(doc_provider, &report);
85+
proposal_doc.validate(provider, &report);
8786
}
8887
},
8988
DocumentType::ProposalTemplate => {},
9089
DocumentType::CommentDocument => {
9190
if let Ok(comment_doc) = CommentDocument::from_signed_doc(doc, &report) {
92-
comment_doc.statefull_validation(doc_provider, &report);
91+
comment_doc.validate(provider, &report);
9392
}
9493
},
9594
DocumentType::CommentTemplate => {},

rust/signed_doc/src/validator/utils.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
33
use catalyst_types::problem_report::ProblemReport;
44

5-
use super::ValidationDataProvider;
65
use crate::{CatalystSignedDocument, DocumentRef};
76

87
/// A helper validation document function, which validates a document from the
98
/// `ValidationDataProvider`.
10-
pub(crate) fn validate_provided_doc(
11-
doc_ref: &DocumentRef, doc_name: &str, provider: &dyn ValidationDataProvider,
12-
report: &ProblemReport, validator: impl Fn(CatalystSignedDocument) -> bool,
13-
) -> bool {
14-
if let Some(doc) = provider.get_doc(doc_ref) {
9+
pub(crate) fn validate_provided_doc<DocProvider, Validator>(
10+
doc_ref: &DocumentRef, doc_name: &str, provider: &DocProvider, report: &ProblemReport,
11+
validator: Validator,
12+
) -> bool
13+
where
14+
DocProvider: Fn(&DocumentRef) -> Option<CatalystSignedDocument>,
15+
Validator: Fn(CatalystSignedDocument) -> bool,
16+
{
17+
if let Some(doc) = provider(doc_ref) {
1518
validator(doc)
1619
} else {
1720
report.functional_validation(

0 commit comments

Comments
 (0)