22
33pub ( crate ) mod utils;
44
5+ use std:: future:: Future ;
6+
57use catalyst_types:: problem_report:: ProblemReport ;
8+ use futures:: future:: BoxFuture ;
69
710use crate :: {
811 doc_types:: { CommentDocument , DocumentType , ProposalDocument } ,
912 error:: CatalystSignedDocError ,
10- CatalystSignedDocument , DocumentRef ,
13+ providers:: CatalystSignedDocumentProvider ,
14+ CatalystSignedDocument ,
1115} ;
1216
1317/// Stateless validation function rule type
14- pub ( crate ) type StatelessRule = fn ( & CatalystSignedDocument , & ProblemReport ) -> bool ;
15- /// Statefull validation function rule type
16- pub ( crate ) type StatefullRule < DocType , DocProvider > =
17- fn ( & DocType , & DocProvider , & ProblemReport ) -> bool ;
18+ pub type StatelessRule = fn ( & CatalystSignedDocument , & ProblemReport ) -> bool ;
1819
1920/// Trait for defining a stateless validation rules.
2021pub trait StatelessValidation
@@ -33,24 +34,31 @@ where Self: 'static
3334}
3435
3536/// Trait for defining a statefull validation rules.
36- pub trait StatefullValidation < DocProvider >
37+ pub trait StatefullValidation < Provider >
3738where
3839 Self : ' static ,
39- DocProvider : ' static + Fn ( & DocumentRef ) -> Option < CatalystSignedDocument > ,
40+ Provider : ' static + CatalystSignedDocumentProvider ,
4041{
41- /// Statefull validation rules
42- const STATEFULL_RULES : & [ StatefullRule < Self , DocProvider > ] ;
42+ /// Statefull validation rules list
43+ fn rules < ' a > (
44+ & ' a self , provider : & ' a Provider , report : & ' a ProblemReport ,
45+ ) -> Vec < BoxFuture < ' a , anyhow:: Result < bool > > > ;
4346
4447 /// Perform a statefull validation, collecting a problem report
4548 ///
4649 /// # Errors
47- /// Returns an error if `provider` will return an error, fails fast in this case.
48- fn validate ( & self , provider : & DocProvider , report : & ProblemReport ) -> anyhow:: Result < bool > {
49- let res = Self :: STATEFULL_RULES
50- . iter ( )
51- . map ( |rule| rule ( self , provider, report) )
52- . all ( |res| res) ;
53- Ok ( res)
50+ /// Returns an error if `provider` return an error.
51+ fn validate (
52+ & self , provider : & Provider , report : & ProblemReport ,
53+ ) -> impl Future < Output = anyhow:: Result < bool > > {
54+ async {
55+ for res in futures:: future:: join_all ( self . rules ( provider, report) ) . await {
56+ if !( res?) {
57+ return Ok ( false ) ;
58+ }
59+ }
60+ Ok ( true )
61+ }
5462 }
5563}
5664
@@ -62,10 +70,10 @@ where
6270/// Returns a report of validation failures and the source error.
6371/// If `provider` returns error, fails fast and placed this error into
6472/// `CatalystSignedDocError::error`.
65- pub fn validate < DocProvider > (
66- doc : & CatalystSignedDocument , provider : & DocProvider ,
73+ pub async fn validate < Provider > (
74+ doc : & CatalystSignedDocument , provider : & Provider ,
6775) -> Result < ( ) , CatalystSignedDocError >
68- where DocProvider : ' static + Fn ( & DocumentRef ) -> Option < CatalystSignedDocument > {
76+ where Provider : ' static + CatalystSignedDocumentProvider {
6977 let report = ProblemReport :: new ( "Catalyst Signed Document Validation" ) ;
7078
7179 let doc_type: DocumentType = match doc. doc_type ( ) . try_into ( ) {
@@ -84,7 +92,7 @@ where DocProvider: 'static + Fn(&DocumentRef) -> Option<CatalystSignedDocument>
8492 } ,
8593 } ;
8694
87- match validate_inner ( doc_type, doc, provider, & report) {
95+ match validate_inner ( doc_type, doc, provider, & report) . await {
8896 Ok ( ( ) ) if report. is_problematic ( ) => {
8997 Err ( CatalystSignedDocError :: new (
9098 report,
@@ -103,23 +111,23 @@ where DocProvider: 'static + Fn(&DocumentRef) -> Option<CatalystSignedDocument>
103111///
104112/// If `provider` returns error, fails fast and placed this error into
105113/// `CatalystSignedDocError::error`.
106- fn validate_inner < DocProvider > (
107- doc_type : DocumentType , doc : & CatalystSignedDocument , provider : & DocProvider ,
114+ async fn validate_inner < Provider > (
115+ doc_type : DocumentType , doc : & CatalystSignedDocument , provider : & Provider ,
108116 report : & ProblemReport ,
109117) -> anyhow:: Result < ( ) >
110118where
111- DocProvider : ' static + Fn ( & DocumentRef ) -> Option < CatalystSignedDocument > ,
119+ Provider : ' static + CatalystSignedDocumentProvider ,
112120{
113121 #[ allow( clippy:: match_same_arms) ]
114122 match doc_type {
115123 DocumentType :: ProposalDocument => {
116124 let doc = ProposalDocument :: from_signed_doc ( doc, report) ?;
117- doc. validate ( provider, report) ?;
125+ doc. validate ( provider, report) . await ?;
118126 } ,
119127 DocumentType :: ProposalTemplate => { } ,
120128 DocumentType :: CommentDocument => {
121129 let doc = CommentDocument :: from_signed_doc ( doc, report) ?;
122- doc. validate ( provider, report) ?;
130+ doc. validate ( provider, report) . await ?;
123131 } ,
124132 DocumentType :: CommentTemplate => { } ,
125133 DocumentType :: ReviewDocument => { } ,
0 commit comments