1 | //! Attribute parsing for the `default` option. |
2 | |
3 | use proc_macro2::Span; |
4 | use syn::{spanned::Spanned, Meta, Result}; |
5 | |
6 | use crate::{DeriveWhere, Error, Trait}; |
7 | |
8 | /// Stores if this variant should be the default when implementing |
9 | /// [`Default`](trait@std::default::Default). |
10 | #[derive (Clone, Copy, Default)] |
11 | #[cfg_attr (test, derive(Debug))] |
12 | pub struct Default(pub Option<Span>); |
13 | |
14 | impl Default { |
15 | /// Token used for the `default` option. |
16 | pub const DEFAULT: &'static str = "default" ; |
17 | |
18 | /// Adds a [`Meta`] to this [`Default`](Self). |
19 | pub fn add_attribute(&mut self, meta: &Meta, derive_wheres: &[DeriveWhere]) -> Result<()> { |
20 | debug_assert!(meta.path().is_ident(Self::DEFAULT)); |
21 | |
22 | if let Meta::Path(path) = meta { |
23 | if self.0.is_some() { |
24 | Err(Error::option_duplicate(path.span(), Self::DEFAULT)) |
25 | } else { |
26 | let mut impl_default = false; |
27 | |
28 | for derive_where in derive_wheres { |
29 | if derive_where.contains(Trait::Default) { |
30 | impl_default = true; |
31 | break; |
32 | } |
33 | } |
34 | |
35 | if impl_default { |
36 | self.0 = Some(path.span()); |
37 | Ok(()) |
38 | } else { |
39 | Err(Error::default(path.span())) |
40 | } |
41 | } |
42 | } else { |
43 | Err(Error::option_syntax(meta.span())) |
44 | } |
45 | } |
46 | } |
47 | |