|
1 |
| -use crate::parsing::{ItemSigConfig, ItemSigConfigParsing, SpannedKey}; |
| 1 | +use crate::parsing::SpannedKey; |
2 | 2 | use crate::util::prelude::*;
|
3 | 3 | use darling::FromMeta;
|
4 | 4 |
|
5 | 5 | const DOCS_CONTEXT: &str = "builder struct's impl block";
|
6 | 6 |
|
7 |
| -fn parse_setter_fn(meta: &syn::Meta) -> Result<SpannedKey<ItemSigConfig>> { |
8 |
| - let params = ItemSigConfigParsing { |
9 |
| - meta, |
10 |
| - reject_self_mentions: Some(DOCS_CONTEXT), |
11 |
| - } |
12 |
| - .parse()?; |
| 7 | +fn parse_docs(meta: &syn::Meta) -> Result<SpannedKey<Vec<syn::Attribute>>> { |
| 8 | + crate::parsing::parse_docs_without_self_mentions(DOCS_CONTEXT, meta) |
| 9 | +} |
13 | 10 |
|
14 |
| - SpannedKey::new(meta.path(), params) |
| 11 | +#[derive(Debug)] |
| 12 | +pub(crate) enum SetterFnName { |
| 13 | + Name(syn::Ident), |
| 14 | + Prefix(syn::Ident), |
15 | 15 | }
|
16 | 16 |
|
17 |
| -fn parse_docs(meta: &syn::Meta) -> Result<SpannedKey<Vec<syn::Attribute>>> { |
18 |
| - crate::parsing::parse_docs_without_self_mentions(DOCS_CONTEXT, meta) |
| 17 | +impl SetterFnName { |
| 18 | + fn new( |
| 19 | + name: Option<SpannedKey<syn::Ident>>, |
| 20 | + prefix: Option<SpannedKey<syn::Ident>>, |
| 21 | + ) -> Result<Option<SpannedKey<Self>>> { |
| 22 | + match (name, prefix) { |
| 23 | + (Some(name), None) => Ok(Some(name.map_value(SetterFnName::Name))), |
| 24 | + (None, Some(prefix)) => Ok(Some(prefix.map_value(SetterFnName::Prefix))), |
| 25 | + (None, None) => Ok(None), |
| 26 | + (Some(name), Some(prefix)) => { |
| 27 | + bail!( |
| 28 | + &name.key, |
| 29 | + "`{}` is mutually exclusive with `{}`", |
| 30 | + name.key, |
| 31 | + prefix.key, |
| 32 | + ); |
| 33 | + } |
| 34 | + } |
| 35 | + } |
19 | 36 | }
|
20 | 37 |
|
21 |
| -#[derive(Debug, FromMeta)] |
| 38 | +#[derive(Debug)] |
22 | 39 | pub(crate) struct SettersConfig {
|
23 |
| - pub(crate) name: Option<SpannedKey<syn::Ident>>, |
| 40 | + pub(crate) name: Option<SpannedKey<SetterFnName>>, |
24 | 41 | pub(crate) vis: Option<SpannedKey<syn::Visibility>>,
|
25 |
| - |
26 |
| - #[darling(rename = "doc", default, with = parse_docs, map = Some)] |
27 | 42 | pub(crate) docs: Option<SpannedKey<Vec<syn::Attribute>>>,
|
28 |
| - |
29 |
| - #[darling(flatten)] |
30 | 43 | pub(crate) fns: SettersFnsConfig,
|
31 | 44 | }
|
32 | 45 |
|
| 46 | +impl FromMeta for SettersConfig { |
| 47 | + fn from_meta(meta: &syn::Meta) -> Result<Self> { |
| 48 | + #[derive(FromMeta)] |
| 49 | + struct Parsed { |
| 50 | + name: Option<SpannedKey<syn::Ident>>, |
| 51 | + prefix: Option<SpannedKey<syn::Ident>>, |
| 52 | + |
| 53 | + vis: Option<SpannedKey<syn::Visibility>>, |
| 54 | + |
| 55 | + #[darling(rename = "doc", default, map = Some, with = parse_docs)] |
| 56 | + docs: Option<SpannedKey<Vec<syn::Attribute>>>, |
| 57 | + |
| 58 | + #[darling(flatten)] |
| 59 | + fns: SettersFnsConfig, |
| 60 | + } |
| 61 | + |
| 62 | + let Parsed { |
| 63 | + name, |
| 64 | + prefix, |
| 65 | + vis, |
| 66 | + docs, |
| 67 | + fns, |
| 68 | + } = Parsed::from_meta(meta)?; |
| 69 | + |
| 70 | + Ok(SettersConfig { |
| 71 | + name: SetterFnName::new(name, prefix)?, |
| 72 | + vis, |
| 73 | + docs, |
| 74 | + fns, |
| 75 | + }) |
| 76 | + } |
| 77 | +} |
| 78 | + |
33 | 79 | #[derive(Debug, FromMeta)]
|
34 | 80 | pub(crate) struct SettersFnsConfig {
|
35 | 81 | /// Config for the setter that accepts the value of type T for a member of
|
36 | 82 | /// type `Option<T>` or with `#[builder(default)]`.
|
37 | 83 | ///
|
38 | 84 | /// By default, it's named `{member}` without any prefix or suffix.
|
39 |
| - #[darling(default, with = parse_setter_fn, map = Some)] |
40 |
| - pub(crate) some_fn: Option<SpannedKey<ItemSigConfig>>, |
| 85 | + pub(crate) some_fn: Option<SpannedKey<SetterFnSigConfig>>, |
41 | 86 |
|
42 | 87 | /// The setter that accepts the value of type `Option<T>` for a member of
|
43 | 88 | /// type `Option<T>` or with `#[builder(default)]`.
|
44 | 89 | ///
|
45 | 90 | /// By default, it's named `maybe_{member}`.
|
46 |
| - #[darling(default, with = parse_setter_fn, map = Some)] |
47 |
| - pub(crate) option_fn: Option<SpannedKey<ItemSigConfig>>, |
| 91 | + pub(crate) option_fn: Option<SpannedKey<SetterFnSigConfig>>, |
| 92 | +} |
| 93 | + |
| 94 | +#[derive(Debug, Default)] |
| 95 | +pub(crate) struct SetterFnSigConfig { |
| 96 | + pub(crate) name: Option<SpannedKey<SetterFnName>>, |
| 97 | + pub(crate) vis: Option<SpannedKey<syn::Visibility>>, |
| 98 | + pub(crate) docs: Option<SpannedKey<Vec<syn::Attribute>>>, |
| 99 | +} |
| 100 | + |
| 101 | +impl FromMeta for SetterFnSigConfig { |
| 102 | + fn from_meta(meta: &syn::Meta) -> Result<Self> { |
| 103 | + if let syn::Meta::NameValue(meta) = meta { |
| 104 | + let val = &meta.value; |
| 105 | + let name = syn::parse2(val.to_token_stream())?; |
| 106 | + |
| 107 | + return Ok(SetterFnSigConfig { |
| 108 | + name: Some(SpannedKey::new(&meta.path, SetterFnName::Name(name))?), |
| 109 | + vis: None, |
| 110 | + docs: None, |
| 111 | + }); |
| 112 | + } |
| 113 | + |
| 114 | + #[derive(Debug, FromMeta)] |
| 115 | + struct Full { |
| 116 | + name: Option<SpannedKey<syn::Ident>>, |
| 117 | + prefix: Option<SpannedKey<syn::Ident>>, |
| 118 | + |
| 119 | + vis: Option<SpannedKey<syn::Visibility>>, |
| 120 | + |
| 121 | + #[darling(rename = "doc", default, map = Some, with = parse_docs)] |
| 122 | + docs: Option<SpannedKey<Vec<syn::Attribute>>>, |
| 123 | + } |
| 124 | + |
| 125 | + let Full { |
| 126 | + name, |
| 127 | + prefix, |
| 128 | + vis, |
| 129 | + docs, |
| 130 | + } = crate::parsing::parse_non_empty_paren_meta_list_or_name_value(meta)?; |
| 131 | + |
| 132 | + let config = SetterFnSigConfig { |
| 133 | + name: SetterFnName::new(name, prefix)?, |
| 134 | + vis, |
| 135 | + docs, |
| 136 | + }; |
| 137 | + |
| 138 | + Ok(config) |
| 139 | + } |
48 | 140 | }
|
0 commit comments