1//! Attribute parsing for the `default` option.
2
3use proc_macro2::Span;
4use syn::{spanned::Spanned, Meta, Result};
5
6use 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))]
12pub struct Default(pub Option<Span>);
13
14impl 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