bon_macros/builder/builder_gen/member/config/
blanket.rs1use super::MemberConfig;
2use crate::builder::builder_gen::member::MemberOrigin;
3use crate::builder::builder_gen::top_level_config::OnConfig;
4use crate::util::prelude::*;
5use std::fmt;
6
7pub(crate) enum BlanketParamName {
8 Into,
9 Overwritable,
10 SettersDocDefaultSkip,
11}
12
13impl fmt::Display for BlanketParamName {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 match self {
16 Self::Into => fmt::Display::fmt(&super::ParamName::Into, f),
17 Self::Overwritable => fmt::Display::fmt(&super::ParamName::Overwritable, f),
18 Self::SettersDocDefaultSkip => f.write_str("setters(doc(default(skip)))"),
19 }
20 }
21}
22
23impl BlanketParamName {
24 fn value_in_on_config(&self, cfg: &OnConfig) -> darling::util::Flag {
25 match self {
26 Self::Into => cfg.into,
27 Self::Overwritable => cfg.overwritable,
28 Self::SettersDocDefaultSkip => cfg.setters.doc.default.skip,
29 }
30 }
31
32 fn value_in_member_config(&self, cfg: &MemberConfig) -> darling::util::Flag {
33 match self {
34 Self::Into => cfg.into,
35 Self::Overwritable => cfg.overwritable,
36 Self::SettersDocDefaultSkip => cfg
37 .setters
38 .as_ref()
39 .and_then(|setters| setters.doc.default.as_ref())
40 .map(|default| default.skip)
41 .unwrap_or_default(),
42 }
43 }
44}
45
46pub(crate) struct EvalBlanketFlagParam<'a> {
47 pub(crate) on: &'a [OnConfig],
48 pub(crate) param_name: BlanketParamName,
49 pub(crate) member_config: &'a MemberConfig,
50 pub(crate) scrutinee: &'a syn::Type,
51 pub(crate) origin: MemberOrigin,
52}
53
54impl EvalBlanketFlagParam<'_> {
55 pub(crate) fn eval(self) -> Result<darling::util::Flag> {
56 let Self {
57 on,
58 param_name,
59 member_config,
60 scrutinee,
61 origin,
62 } = self;
63
64 let verdict_from_on = on
65 .iter()
66 .map(|params| Ok((params, scrutinee.matches(¶ms.type_pattern)?)))
67 .collect::<Result<Vec<_>>>()?
68 .into_iter()
69 .filter(|(_, matched)| *matched)
70 .map(|(params, _)| param_name.value_in_on_config(params))
71 .find(darling::util::Flag::is_present);
72
73 let value_in_member = param_name.value_in_member_config(member_config);
74 let flag = match (verdict_from_on, value_in_member.is_present()) {
75 (Some(_), true) => {
76 bail!(
77 &value_in_member.span(),
78 "this `#[builder({param_name})]` attribute is redundant, because \
79 `{param_name}` is already implied for this member via the \
80 `#[builder(on(...))]` at the top of the {}",
81 origin.parent_construct(),
82 );
83 }
84 (Some(flag), false) => flag,
85 (None, _) => value_in_member,
86 };
87
88 Ok(flag)
89 }
90}