bon_macros/builder/builder_gen/member/config/with/
mod.rs

1mod closure;
2
3pub(crate) use closure::*;
4
5use crate::util::prelude::*;
6use darling::FromMeta;
7
8#[derive(Debug)]
9pub(crate) enum WithConfig {
10    /// Closure syntax e.g. `#[builder(with = |param: Type| body)]`
11    Closure(SetterClosure),
12
13    /// Well-known path [`Option::Some`]
14    Some(syn::Path),
15
16    /// Well-known path [`FromIterator::from_iter`] or `<_>::from_iter`
17    FromIter(syn::ExprPath),
18}
19
20impl WithConfig {
21    pub(crate) fn as_closure(&self) -> Option<&SetterClosure> {
22        match self {
23            Self::Closure(closure) => Some(closure),
24            _ => None,
25        }
26    }
27}
28
29impl FromMeta for WithConfig {
30    fn from_meta(meta: &syn::Meta) -> darling::Result<Self> {
31        let err = || {
32            err!(
33                meta,
34                "expected a closure e.g. `#[builder(with = |param: T| expression)]` or \
35                a well-known function path which could be one of:\n\
36                - #[builder(with = Some)]\n\
37                - #[builder(with = FromIterator::from_iter)]\n\
38                - #[builder(with = <_>::from_iter)] (same as above, but shorter)",
39            )
40        };
41
42        let name_val = match meta {
43            syn::Meta::NameValue(meta) => meta,
44            _ => return Err(err()),
45        };
46
47        if let syn::Expr::Closure(_) = name_val.value {
48            return SetterClosure::from_meta(meta).map(Self::Closure);
49        }
50
51        let path = match &name_val.value {
52            syn::Expr::Path(path) => path,
53            _ => return Err(err()),
54        };
55
56        crate::parsing::reject_syntax("attribute", &path.attrs.first())?;
57
58        if *path == syn::parse_quote!(Some) {
59            return Ok(Self::Some(path.path.clone()));
60        }
61
62        if *path == syn::parse_quote!(FromIterator::from_iter)
63            || *path == syn::parse_quote!(<_>::from_iter)
64        {
65            return Ok(Self::FromIter(path.clone()));
66        }
67
68        Err(err())
69    }
70}