Skip to content

Commit 4cce98b

Browse files
authored
[ISSUE #1474]⚡Optimize derive RequestHeaderCodec and add required attribute🚀 (#1475)
1 parent 8c653e8 commit 4cce98b

File tree

2 files changed

+109
-58
lines changed

2 files changed

+109
-58
lines changed

rocketmq-macros/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::request_header_custom::request_header_codec_inner;
2626
mod remoting_serializable;
2727
mod request_header_custom;
2828

29-
#[proc_macro_derive(RequestHeaderCodec)]
29+
#[proc_macro_derive(RequestHeaderCodec, attributes(required))]
3030
pub fn request_header_codec(input: TokenStream) -> TokenStream {
3131
request_header_codec_inner(input)
3232
}

rocketmq-macros/src/request_header_custom.rs

Lines changed: 108 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)