apache_avro_derive/attributes/
serde.rs1use darling::{FromAttributes, FromMeta};
29use syn::Expr;
30
31use crate::case::RenameRule;
32
33#[derive(Debug, Default, FromMeta, PartialEq, Eq)]
42#[darling(from_expr = RenameAll::from_expr)]
43pub struct RenameAll {
44 #[darling(default)]
45 pub serialize: RenameRule,
46 #[darling(default)]
47 pub deserialize: RenameRule,
48}
49
50impl From<RenameRule> for RenameAll {
51 fn from(value: RenameRule) -> Self {
52 Self {
53 serialize: value,
54 deserialize: value,
55 }
56 }
57}
58
59impl RenameAll {
60 fn from_expr(expr: &Expr) -> darling::Result<Self> {
61 let Expr::Lit(lit) = expr else {
62 return Err(darling::Error::custom("Expected a string literal!"));
63 };
64 let rule = RenameRule::from_value(&lit.lit)?;
65 Ok(RenameAll::from(rule))
66 }
67}
68
69#[derive(Debug, FromMeta, PartialEq)]
78#[darling(from_expr = |expr| Ok(SerdeDefault::Expr(expr.clone())))]
79pub enum SerdeDefault {
80 #[darling(word, skip)]
81 UseTrait,
82 Expr(Expr),
83}
84
85#[derive(Debug, FromAttributes)]
87#[darling(attributes(serde))]
88pub struct ContainerAttributes {
89 pub rename: Option<String>,
91 #[darling(default)]
93 pub rename_all: RenameAll,
94 #[darling(default, rename = "rename_all_fields")]
96 pub _rename_all_fields: RenameAll,
97 #[darling(default, rename = "deny_unknown_fields")]
99 pub _deny_unknown_fields: bool,
100 pub tag: Option<String>,
105 pub content: Option<String>,
107 #[darling(default)]
111 pub untagged: bool,
112 #[darling(default, rename = "bound")]
114 pub _bound: Option<String>,
115 #[darling(rename = "default")]
117 pub _default: Option<SerdeDefault>,
118 pub remote: Option<String>,
122 #[darling(default)]
124 pub transparent: bool,
125 #[darling(default, rename = "from")]
127 pub _from: Option<String>,
128 #[darling(default, rename = "try_from")]
130 pub _try_from: Option<String>,
131 #[darling(default, rename = "into")]
133 pub _into: Option<String>,
134 #[darling(default, rename = "crate")]
136 pub _crate: Option<String>,
137 #[darling(default, rename = "expecting")]
139 pub _expecting: Option<String>,
140 #[darling(default)]
142 pub variant_identifier: bool,
143 #[darling(default)]
145 pub field_identifier: bool,
146}
147
148#[derive(Debug, FromAttributes)]
150#[darling(attributes(serde))]
151pub struct VariantAttributes {
152 #[darling(default)]
154 pub rename: Option<String>,
155 #[darling(multiple, rename = "alias")]
157 pub _alias: Vec<String>,
158 #[darling(default, rename = "rename_all")]
159 pub _rename_all: RenameAll,
160 #[darling(default, rename = "skip")]
162 pub _skip: bool,
163 #[darling(default, rename = "skip_serializing")]
165 pub _skip_serializing: bool,
166 #[darling(default, rename = "skip_deserializing")]
168 pub _skip_deserializing: bool,
169 #[darling(rename = "serialize_with")]
171 pub _serialize_with: Option<String>,
172 #[darling(rename = "deserialize_with")]
174 pub _deserialize_with: Option<String>,
175 #[darling(rename = "with")]
177 pub _with: Option<String>,
178 #[darling(rename = "bound")]
180 pub _bound: Option<String>,
181 #[darling(rename = "borrow")]
183 pub _borrow: Option<SerdeBorrow>,
184 #[darling(default)]
186 pub other: bool,
187 #[darling(default)]
189 pub untagged: bool,
190}
191
192#[derive(Debug, FromMeta, PartialEq)]
201#[darling(from_expr = |expr| Ok(SerdeBorrow::Expr(expr.clone())))]
202pub enum SerdeBorrow {
203 #[darling(word, skip)]
204 Default,
205 Expr(Expr),
206}
207
208#[derive(Debug, FromAttributes)]
210#[darling(attributes(serde))]
211pub struct FieldAttributes {
212 #[darling(default)]
214 pub rename: Option<String>,
215 #[darling(multiple)]
217 pub alias: Vec<String>,
218 #[darling(rename = "default")]
220 pub _default: Option<SerdeDefault>,
221 #[darling(default)]
222 pub flatten: bool,
223 #[darling(default)]
225 pub skip: bool,
226 #[darling(default)]
228 pub skip_serializing: bool,
229 #[darling(default)]
231 pub skip_deserializing: bool,
232 pub skip_serializing_if: Option<String>,
234 #[darling(rename = "serialize_with")]
236 pub _serialize_with: Option<String>,
237 #[darling(rename = "deserialize_with")]
239 pub _deserialize_with: Option<String>,
240 pub with: Option<String>,
242 #[darling(rename = "borrow")]
244 pub _borrow: Option<SerdeBorrow>,
245 pub getter: Option<String>,
247}
248
249#[cfg(test)]
250mod tests {
251 use crate::{
252 RenameRule,
253 attributes::serde::{ContainerAttributes, RenameAll, SerdeDefault},
254 };
255 use darling::FromAttributes;
256 use syn::DeriveInput;
257
258 #[test]
259 fn test_rename_all() {
260 let derive: DeriveInput = syn::parse_quote! {
261 #[serde(rename_all = "lowercase")]
262 struct Config {
263 field: String,
264 }
265 };
266 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
267 assert_eq!(input.rename_all, RenameAll::from(RenameRule::LowerCase));
268
269 let derive: DeriveInput = syn::parse_quote! {
270 #[serde(rename_all(serialize = "lowercase"))]
271 struct Config {
272 field: String,
273 }
274 };
275 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
276 assert_eq!(
277 input.rename_all,
278 RenameAll {
279 serialize: RenameRule::LowerCase,
280 deserialize: RenameRule::None
281 }
282 );
283
284 let derive: DeriveInput = syn::parse_quote! {
285 #[serde(rename_all(deserialize = "lowercase"))]
286 struct Config {
287 field: String,
288 }
289 };
290 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
291 assert_eq!(
292 input.rename_all,
293 RenameAll {
294 serialize: RenameRule::None,
295 deserialize: RenameRule::LowerCase
296 }
297 );
298
299 let derive: DeriveInput = syn::parse_quote! {
300 struct Config {
301 field: String,
302 }
303 };
304 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
305 assert_eq!(input.rename_all, RenameAll::from(RenameRule::None));
306 }
307
308 #[test]
309 fn test_default() {
310 let derive: DeriveInput = syn::parse_quote! {
311 #[serde(default)]
312 struct Config {
313 field: String,
314 }
315 };
316 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
317 assert_eq!(input._default, Some(SerdeDefault::UseTrait));
318
319 let derive: DeriveInput = syn::parse_quote! {
320 #[serde(default = "some::path")]
321 struct Config {
322 field: String,
323 }
324 };
325 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
326 assert!(matches!(input._default, Some(SerdeDefault::Expr(_))));
327
328 let derive: DeriveInput = syn::parse_quote! {
329 struct Config {
330 field: String,
331 }
332 };
333 let input = ContainerAttributes::from_attributes(&derive.attrs).unwrap();
334 assert_eq!(input._default, None);
335 }
336}