11//! `parameters` rule type impl.
22
3+ use std:: collections:: HashMap ;
4+
5+ use catalyst_signed_doc_spec:: {
6+ is_required:: IsRequired , metadata:: parameters:: Parameters , DocSpec , DocumentName ,
7+ } ;
38use catalyst_types:: problem_report:: ProblemReport ;
49use futures:: FutureExt ;
510
@@ -14,7 +19,7 @@ pub(crate) enum ParametersRule {
1419 /// Is `parameters` specified
1520 Specified {
1621 /// expected `type` field of the parameter doc
17- exp_parameters_type : Vec < DocType > ,
22+ allowed_type : Vec < DocType > ,
1823 /// optional flag for the `parameters` field
1924 optional : bool ,
2025 } ,
@@ -24,6 +29,46 @@ pub(crate) enum ParametersRule {
2429}
2530
2631impl ParametersRule {
32+ /// Generating `ParametersRule` from specs
33+ pub ( crate ) fn new (
34+ docs : & HashMap < DocumentName , DocSpec > ,
35+ spec : & Parameters ,
36+ ) -> anyhow:: Result < Self > {
37+ let optional = match spec. required {
38+ IsRequired :: Yes => false ,
39+ IsRequired :: Optional => true ,
40+ IsRequired :: Excluded => {
41+ anyhow:: ensure!(
42+ spec. doc_type. is_empty( ) && spec. multiple. is_none( ) ,
43+ "'type' and 'multiple' fields could not been specified when 'required' is 'excluded' for 'template' metadata definition"
44+ ) ;
45+ return Ok ( Self :: NotSpecified ) ;
46+ } ,
47+ } ;
48+
49+ anyhow:: ensure!( !spec. doc_type. is_empty( ) , "'type' field should exists and has at least one entry for the required 'ref' metadata definition" ) ;
50+ anyhow:: ensure!(
51+ spec. multiple. is_some_and( |v| !v) ,
52+ "'multiple' field should be only set to false for the required 'reply' metadata definition"
53+ ) ;
54+
55+ let allowed_type = spec. doc_type . iter ( ) . try_fold (
56+ Vec :: new ( ) ,
57+ |mut res, doc_name| -> anyhow:: Result < _ > {
58+ let docs_spec = docs. get ( doc_name) . ok_or ( anyhow:: anyhow!(
59+ "cannot find a document definition {doc_name}"
60+ ) ) ?;
61+ res. push ( docs_spec. doc_type . as_str ( ) . parse ( ) ?) ;
62+ Ok ( res)
63+ } ,
64+ ) ?;
65+
66+ Ok ( Self :: Specified {
67+ allowed_type,
68+ optional,
69+ } )
70+ }
71+
2772 /// Field validation rule
2873 pub ( crate ) async fn check < Provider > (
2974 & self ,
@@ -35,7 +80,7 @@ impl ParametersRule {
3580 {
3681 let context: & str = "Parameter rule check" ;
3782 if let Self :: Specified {
38- exp_parameters_type,
83+ allowed_type : exp_parameters_type,
3984 optional,
4085 } = self
4186 {
@@ -722,15 +767,15 @@ mod tests {
722767 let doc = doc_gen ( & exp_param_types, & mut provider) ;
723768
724769 let non_optional_res = ParametersRule :: Specified {
725- exp_parameters_type : exp_param_types. to_vec ( ) ,
770+ allowed_type : exp_param_types. to_vec ( ) ,
726771 optional : false ,
727772 }
728773 . check ( & doc, & provider)
729774 . await
730775 . unwrap ( ) ;
731776
732777 let optional_res = ParametersRule :: Specified {
733- exp_parameters_type : exp_param_types. to_vec ( ) ,
778+ allowed_type : exp_param_types. to_vec ( ) ,
734779 optional : true ,
735780 }
736781 . check ( & doc, & provider)
@@ -745,7 +790,7 @@ mod tests {
745790 async fn ref_specified_optional_test ( ) {
746791 let provider = TestCatalystProvider :: default ( ) ;
747792 let rule = ParametersRule :: Specified {
748- exp_parameters_type : vec ! [ UuidV4 :: new( ) . into( ) ] ,
793+ allowed_type : vec ! [ UuidV4 :: new( ) . into( ) ] ,
749794 optional : true ,
750795 } ;
751796
@@ -754,7 +799,7 @@ mod tests {
754799
755800 let provider = TestCatalystProvider :: default ( ) ;
756801 let rule = ParametersRule :: Specified {
757- exp_parameters_type : vec ! [ UuidV4 :: new( ) . into( ) ] ,
802+ allowed_type : vec ! [ UuidV4 :: new( ) . into( ) ] ,
758803 optional : false ,
759804 } ;
760805
0 commit comments