| 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 | |