@@ -44,106 +44,157 @@ pub(super) fn request_header_codec_inner(
44
44
45
45
//build CommandCustomHeader impl
46
46
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 ! {
60
70
const #static_name: & ' static str = #camel_case_name;
61
71
} ,
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 ! {
67
77
if let Some ( ref value) = self . #field_name {
68
78
map. insert (
69
79
cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
70
80
value. clone( )
71
81
) ;
72
82
}
73
83
}
74
- } else if type_name == "String" {
75
- quote ! {
84
+ } else if type_name == "String" {
85
+ quote ! {
76
86
if let Some ( ref value) = self . #field_name {
77
87
map. insert (
78
88
cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
79
89
cheetah_string:: CheetahString :: from_string( value. clone( ) )
80
90
) ;
81
91
}
82
92
}
83
- } else {
84
- quote ! {
93
+ } else {
94
+ quote ! {
85
95
if let Some ( value) = self . #field_name {
86
96
map. insert (
87
97
cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
88
98
cheetah_string:: CheetahString :: from_string( value. to_string( ) )
89
99
) ;
90
100
}
91
101
}
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 ! {
97
107
map. insert (
98
108
cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
99
109
self . #field_name. clone( )
100
110
) ;
101
111
}
102
- } else if type_name == "String" {
103
- quote ! {
112
+ } else if type_name == "String" {
113
+ quote ! {
104
114
map. insert (
105
115
cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
106
116
cheetah_string:: CheetahString :: from_string( self . #field_name. clone( ) )
107
117
) ;
108
118
}
109
- } else {
110
- quote ! {
119
+ } else {
120
+ quote ! {
111
121
map. insert (
112
122
cheetah_string:: CheetahString :: from_static_str( Self :: #static_name) ,
113
123
cheetah_string:: CheetahString :: from_string( self . #field_name. to_string( ) )
114
124
) ;
115
125
}
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 ! {
123
144
#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
+ ) ,
124
156
}
125
- } else {
126
- quote ! {
157
+ } else {
158
+ quote ! {
127
159
#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
+ ) ) ?,
128
173
}
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 ! {
135
176
#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 ( ) ;
147
198
let expanded: TokenStream2 = quote ! {
148
199
impl #struct_name {
149
200
#( #static_fields) *
0 commit comments