1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use syn::{spanned::Spanned, Attribute, Fields, Meta, NestedMeta, Result, Variant};
use crate::{Default, DeriveWhere, Error, Skip, DERIVE_WHERE};
#[derive(Default)]
pub struct VariantAttr {
pub default: Default,
pub skip_inner: Skip,
}
impl VariantAttr {
pub fn from_attrs(
attrs: &[Attribute],
derive_wheres: &[DeriveWhere],
variant: &Variant,
) -> Result<Self> {
let mut self_ = VariantAttr::default();
for attr in attrs {
if attr.path.is_ident(DERIVE_WHERE) {
match attr.parse_meta() {
Ok(meta) => self_.add_meta(&meta, derive_wheres, variant)?,
Err(error) => return Err(Error::attribute_syntax(attr.span(), error)),
}
}
}
Ok(self_)
}
fn add_meta(
&mut self,
meta: &Meta,
derive_wheres: &[DeriveWhere],
variant: &Variant,
) -> Result<()> {
debug_assert!(meta.path().is_ident(DERIVE_WHERE));
if let Meta::List(list) = meta {
if list.nested.is_empty() {
return Err(Error::empty(list.span()));
}
for nested_meta in &list.nested {
match nested_meta {
NestedMeta::Meta(meta) => {
if meta.path().is_ident(Skip::SKIP_INNER) {
match &variant.fields {
Fields::Named(fields) if fields.named.is_empty() => {
return Err(Error::option_skip_empty(variant.span()))
}
Fields::Unnamed(fields) if fields.unnamed.is_empty() => {
return Err(Error::option_skip_empty(variant.span()))
}
Fields::Unit => {
return Err(Error::option_skip_empty(variant.span()))
}
_ => self.skip_inner.add_attribute(derive_wheres, None, meta)?,
}
} else if meta.path().is_ident(Default::DEFAULT) {
self.default.add_attribute(meta, derive_wheres)?;
} else {
return Err(Error::option(meta.path().span()));
}
}
_ => return Err(Error::option_syntax(nested_meta.span())),
}
}
Ok(())
} else {
Err(Error::option_syntax(meta.span()))
}
}
}