@@ -44,106 +44,157 @@ pub(super) fn request_header_codec_inner(
4444
4545 //build CommandCustomHeader impl
4646 let ( static_fields, ( to_maps, from_map) ) : ( Vec < _ > , ( Vec < _ > , Vec < _ > ) ) = fields
47- . iter ( )
48- . map ( |field| {
49- let field_name = field. ident . as_ref ( ) . unwrap ( ) ;
50- //Determining whether it is an Option type or a direct data type
51- //This will lead to different ways of processing in the future.
52- let has_option = is_option_type ( & field. ty ) ;
53- let camel_case_name = snake_to_camel_case ( & format ! ( "{}" , field_name) ) ;
54- let static_name = Ident :: new (
55- & format ! ( "{}" , field_name) . to_ascii_uppercase ( ) ,
56- field_name. span ( ) ,
57- ) ;
58- (
59- quote ! {
47+ . iter ( )
48+ . map ( |field| {
49+ let field_name = field. ident . as_ref ( ) . unwrap ( ) ;
50+ let mut required = false ;
51+
52+ for attr in & field. attrs {
53+ if let Some ( ident) = attr. path ( ) . get_ident ( ) {
54+ if ident == "required" {
55+ required = true ;
56+ }
57+ }
58+ }
59+
60+ //Determining whether it is an Option type or a direct data type
61+ //This will lead to different ways of processing in the future.
62+ let has_option = is_option_type ( & field. ty ) ;
63+ let camel_case_name = snake_to_camel_case ( & format ! ( "{}" , field_name) ) ;
64+ let static_name = Ident :: new (
65+ & format ! ( "{}" , field_name) . to_ascii_uppercase ( ) ,
66+ field_name. span ( ) ,
67+ ) ;
68+ (
69+ quote ! {
6070 const #static_name: & ' static str = #camel_case_name;
6171 } ,
62- (
63- if let Some ( value) = has_option {
64- let type_name = get_type_name ( value) ;
65- if type_name == "CheetahString" {
66- quote ! {
72+ (
73+ if let Some ( value) = has_option {
74+ let type_name = get_type_name ( value) ;
75+ if type_name == "CheetahString" {
76+ quote ! {
6777 if let Some ( ref value) = self . #field_name {
6878 map. insert (
6979 cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
7080 value. clone( )
7181 ) ;
7282 }
7383 }
74- } else if type_name == "String" {
75- quote ! {
84+ } else if type_name == "String" {
85+ quote ! {
7686 if let Some ( ref value) = self . #field_name {
7787 map. insert (
7888 cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
7989 cheetah_string:: CheetahString :: from_string( value. clone( ) )
8090 ) ;
8191 }
8292 }
83- } else {
84- quote ! {
93+ } else {
94+ quote ! {
8595 if let Some ( value) = self . #field_name {
8696 map. insert (
8797 cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
8898 cheetah_string:: CheetahString :: from_string( value. to_string( ) )
8999 ) ;
90100 }
91101 }
92- }
93- } else {
94- let type_name = get_type_name ( & field. ty ) ;
95- if type_name == "CheetahString" {
96- quote ! {
102+ }
103+ } else {
104+ let type_name = get_type_name ( & field. ty ) ;
105+ if type_name == "CheetahString" {
106+ quote ! {
97107 map. insert (
98108 cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
99109 self . #field_name. clone( )
100110 ) ;
101111 }
102- } else if type_name == "String" {
103- quote ! {
112+ } else if type_name == "String" {
113+ quote ! {
104114 map. insert (
105115 cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
106116 cheetah_string:: CheetahString :: from_string( self . #field_name. clone( ) )
107117 ) ;
108118 }
109- } else {
110- quote ! {
119+ } else {
120+ quote ! {
111121 map. insert (
112122 cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
113123 cheetah_string:: CheetahString :: from_string( self . #field_name. to_string( ) )
114124 ) ;
115125 }
116- }
117- } ,
118- // build FromMap impl
119- if let Some ( value) = has_option {
120- let type_name = get_type_name ( value) ;
121- if type_name == "CheetahString" || type_name == "String" {
122- quote ! {
126+ }
127+ } ,
128+ // build FromMap impl
129+ if let Some ( value) = has_option {
130+ let type_name = get_type_name ( value) ;
131+ if type_name == "CheetahString" || type_name == "String" {
132+ if required {
133+ quote ! {
134+ #field_name: Some (
135+ map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) )
136+ . cloned( )
137+ . ok_or( Self :: Error :: RemotingCommandError (
138+ format!( "Missing {} field" , Self :: #static_name) ,
139+ ) ) ?
140+ ) ,
141+ }
142+ } else {
143+ quote ! {
123144 #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . cloned( ) ,
145+ }
146+ }
147+ } else if required {
148+ quote ! {
149+ #field_name: Some (
150+ map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . ok_or( Self :: Error :: RemotingCommandError (
151+ format!( "Missing {} field" , Self :: #static_name) ,
152+ ) ) ?
153+ . parse:: <#value>( )
154+ . map_err( |_| Self :: Error :: RemotingCommandError ( format!( "Parse {} field error" , Self :: #static_name) ) ) ?
155+ ) ,
124156 }
125- } else {
126- quote ! {
157+ } else {
158+ quote ! {
127159 #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . and_then( |s| s. parse:: <#value>( ) . ok( ) ) ,
160+ }
161+ }
162+ } else {
163+ let types = & field. ty ;
164+ let type_name = get_type_name ( types) ;
165+ if type_name == "CheetahString" || type_name == "String" {
166+ if required {
167+ quote ! {
168+ #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) )
169+ . cloned( )
170+ . ok_or( Self :: Error :: RemotingCommandError (
171+ format!( "Missing {} field" , Self :: #static_name) ,
172+ ) ) ?,
128173 }
129- }
130- } else {
131- let types = & field. ty ;
132- let type_name = get_type_name ( types) ;
133- if type_name == "CheetahString" || type_name == "String" {
134- quote ! {
174+ } else {
175+ quote ! {
135176 #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . cloned( ) . unwrap_or_default( ) ,
136- }
137- } else {
138- quote ! {
139- #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . and_then( |s| s. parse:: <#types>( ) . ok( ) ) . unwrap_or_default( ) ,
140- }
141- }
142- }
143- )
144- )
145- } )
146- . unzip ( ) ;
177+ }
178+ }
179+ } else if required {
180+ quote ! {
181+ #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . ok_or( Self :: Error :: RemotingCommandError (
182+ format!( "Missing {} field" , Self :: #static_name) ,
183+ ) ) ?
184+ . parse:: <#types>( )
185+ . map_err( |_| Self :: Error :: RemotingCommandError ( format!( "Parse {} field error" , Self :: #static_name) ) ) ?,
186+ }
187+ } else {
188+ quote ! {
189+ #field_name: map. get( & cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ) . and_then( |s| s. parse:: <#types>( ) . ok( ) ) . unwrap_or_default( ) ,
190+ }
191+ }
192+
193+ }
194+ )
195+ )
196+ } )
197+ . unzip ( ) ;
147198 let expanded: TokenStream2 = quote ! {
148199 impl #struct_name {
149200 #( #static_fields) *
0 commit comments