@@ -2,38 +2,36 @@ use proc_macro2::TokenStream;
22use quote:: quote;
33use syn:: { Field , Result } ;
44
5- use crate :: validations:: { Email , Length , Url } ;
5+ use crate :: {
6+ validation:: Validation ,
7+ validations:: { Email , Length , Url } ,
8+ } ;
69
710pub struct ValidateField {
811 expr : TokenStream ,
9- // TODO: Consider using a trait for validations.
10- email : Option < Email > ,
11- length : Option < Length > ,
12- url : Option < Url > ,
12+ validations : Vec < Box < dyn Validation > > ,
1313}
1414
1515impl ValidateField {
1616 pub fn parse ( expr : TokenStream , field : & Field ) -> Result < Self > {
1717 let mut result = Self {
1818 expr,
19- email : None ,
20- length : None ,
21- url : None ,
19+ validations : vec ! [ ] ,
2220 } ;
2321
2422 for attr in & field. attrs {
2523 if attr. path ( ) . is_ident ( "validate" ) {
2624 attr. parse_nested_meta ( |meta| {
2725 if meta. path . is_ident ( "email" ) {
28- result. email = Some ( Email :: parse ( & meta) ?) ;
26+ result. validations . push ( Box :: new ( Email :: parse ( & meta) ?) ) ;
2927
3028 Ok ( ( ) )
3129 } else if meta. path . is_ident ( "length" ) {
32- result. length = Some ( Length :: parse ( & meta) ?) ;
30+ result. validations . push ( Box :: new ( Length :: parse ( & meta) ?) ) ;
3331
3432 Ok ( ( ) )
3533 } else if meta. path . is_ident ( "url" ) {
36- result. url = Some ( Url :: parse ( & meta) ?) ;
34+ result. validations . push ( Box :: new ( Url :: parse ( & meta) ?) ) ;
3735
3836 Ok ( ( ) )
3937 } else {
@@ -49,26 +47,25 @@ impl ValidateField {
4947 pub fn error_type ( & self ) -> TokenStream {
5048 // TODO: Merge error types
5149
52- if self . email . is_some ( ) {
53- quote ! ( EmailError )
54- } else if self . length . is_some ( ) {
55- quote ! ( LengthError <usize >)
56- } else if self . url . is_some ( ) {
57- quote ! ( UrlError )
58- } else {
59- quote ! ( ( ) )
60- }
50+ self . validations
51+ . first ( )
52+ . map ( |validation| validation. error_type ( ) )
53+ . unwrap_or_else ( || quote ! ( ( ) ) )
6154 }
6255
6356 pub fn sync_validations ( & self ) -> Vec < TokenStream > {
64- let email = self . email . as_ref ( ) . map ( |email| email . tokens ( & self . expr ) ) ;
65- let length = self . length . as_ref ( ) . map ( |length| length . tokens ( & self . expr ) ) ;
66- let url = self . url . as_ref ( ) . map ( |url| url . tokens ( & self . expr ) ) ;
67-
68- [ email , length , url ] . into_iter ( ) . flatten ( ) . collect ( )
57+ self . validations
58+ . iter ( )
59+ . filter ( |validation| !validation . is_async ( ) )
60+ . map ( |validation| validation . tokens ( & self . expr ) )
61+ . collect ( )
6962 }
7063
7164 pub fn async_validations ( & self ) -> Vec < TokenStream > {
72- vec ! [ ]
65+ self . validations
66+ . iter ( )
67+ . filter ( |validation| validation. is_async ( ) )
68+ . map ( |validation| validation. tokens ( & self . expr ) )
69+ . collect ( )
7370 }
7471}
0 commit comments