1use std::{borrow::Cow, vec::IntoIter};
2
3use crate::BuildMethod;
4
5use darling::util::{Flag, PathList};
6use darling::{self, Error, FromMeta};
7use proc_macro2::{Span, TokenStream};
8use syn::parse::{ParseStream, Parser};
9use syn::Meta;
10use syn::{self, spanned::Spanned, Attribute, Generics, Ident, Path};
11
12use crate::{
13 BlockContents, Builder, BuilderField, BuilderFieldType, BuilderPattern, DefaultExpression,
14 DeprecationNotes, Each, FieldConversion, Initializer, Setter,
15};
16
17trait Visibility {
22 fn public(&self) -> &Flag;
23 fn private(&self) -> &Flag;
24 fn explicit(&self) -> Option<&syn::Visibility>;
25
26 fn as_expressed_vis(&self) -> Option<Cow<syn::Visibility>> {
32 let declares_public = self.public().is_present();
33 let declares_private = self.private().is_present();
34 let declares_explicit = self.explicit().is_some();
35
36 if declares_private {
37 assert!(!declares_public && !declares_explicit);
38 Some(Cow::Owned(syn::Visibility::Inherited))
39 } else if let Some(vis) = self.explicit() {
40 assert!(!declares_public);
41 Some(Cow::Borrowed(vis))
42 } else if declares_public {
43 Some(Cow::Owned(syn::parse_quote!(pub)))
44 } else {
45 None
46 }
47 }
48}
49
50fn no_visibility_conflict<T: Visibility>(v: &T) -> darling::Result<()> {
51 let declares_public = v.public().is_present();
52 let declares_private = v.private().is_present();
53 if let Some(vis) = v.explicit() {
54 if declares_public || declares_private {
55 Err(
56 Error::custom(r#"`vis="..."` cannot be used with `public` or `private`"#)
57 .with_span(vis),
58 )
59 } else {
60 Ok(())
61 }
62 } else if declares_public && declares_private {
63 Err(
64 Error::custom(r#"`public` and `private` cannot be used together"#)
65 .with_span(v.public()),
66 )
67 } else {
68 Ok(())
69 }
70}
71
72#[derive(Debug, Clone, FromMeta)]
76#[darling(default)]
77pub struct BuildFn {
78 skip: bool,
79 name: Ident,
80 validate: Option<Path>,
81 public: Flag,
82 private: Flag,
83 vis: Option<syn::Visibility>,
84 error: Option<Path>,
98}
99
100impl Default for BuildFn {
101 fn default() -> Self {
102 BuildFn {
103 skip: false,
104 name: Ident::new("build", Span::call_site()),
105 validate: None,
106 public: Default::default(),
107 private: Default::default(),
108 vis: None,
109 error: None,
110 }
111 }
112}
113
114impl Visibility for BuildFn {
115 fn public(&self) -> &Flag {
116 &self.public
117 }
118
119 fn private(&self) -> &Flag {
120 &self.private
121 }
122
123 fn explicit(&self) -> Option<&syn::Visibility> {
124 self.vis.as_ref()
125 }
126}
127
128#[derive(Debug, Clone, Default, FromMeta)]
130pub struct StructLevelFieldMeta {
131 public: Flag,
132 private: Flag,
133 vis: Option<syn::Visibility>,
134}
135
136impl Visibility for StructLevelFieldMeta {
137 fn public(&self) -> &Flag {
138 &self.public
139 }
140
141 fn private(&self) -> &Flag {
142 &self.private
143 }
144
145 fn explicit(&self) -> Option<&syn::Visibility> {
146 self.vis.as_ref()
147 }
148}
149
150#[derive(Debug, Clone, Default, FromMeta)]
156pub struct FieldLevelFieldMeta {
157 public: Flag,
158 private: Flag,
159 vis: Option<syn::Visibility>,
160 #[darling(rename = "type")]
162 builder_type: Option<syn::Type>,
163 build: Option<BlockContents>,
165}
166
167impl Visibility for FieldLevelFieldMeta {
168 fn public(&self) -> &Flag {
169 &self.public
170 }
171
172 fn private(&self) -> &Flag {
173 &self.private
174 }
175
176 fn explicit(&self) -> Option<&syn::Visibility> {
177 self.vis.as_ref()
178 }
179}
180
181#[derive(Debug, Clone, Default, FromMeta)]
182pub struct StructLevelSetter {
183 prefix: Option<Ident>,
184 into: Option<bool>,
185 strip_option: Option<bool>,
186 skip: Option<bool>,
187}
188
189impl StructLevelSetter {
190 pub fn enabled(&self) -> Option<bool> {
193 self.skip.map(|x| !x)
194 }
195}
196
197fn parse_each(meta: &Meta) -> darling::Result<Option<Each>> {
204 if let Meta::NameValue(mnv) = meta {
205 if let syn::Lit::Str(v) = &mnv.lit {
206 v.parse::<Ident>()
207 .map(Each::from)
208 .map(Some)
209 .map_err(|_| darling::Error::unknown_value(&v.value()).with_span(v))
210 } else {
211 Err(darling::Error::unexpected_lit_type(&mnv.lit))
212 }
213 } else {
214 Each::from_meta(meta).map(Some)
215 }
216}
217
218#[derive(Debug, Clone, Default, FromMeta)]
222pub struct FieldLevelSetter {
223 prefix: Option<Ident>,
224 name: Option<Ident>,
225 into: Option<bool>,
226 strip_option: Option<bool>,
227 skip: Option<bool>,
228 custom: Option<bool>,
229 #[darling(with = "parse_each")]
230 each: Option<Each>,
231}
232
233impl FieldLevelSetter {
234 pub fn setter_enabled(&self) -> Option<bool> {
237 if self.custom.is_some() {
238 return self.custom.map(|x| !x);
239 }
240
241 self.field_enabled()
242 }
243
244 pub fn field_enabled(&self) -> Option<bool> {
249 if self.skip.is_some() {
250 return self.skip.map(|x| !x);
251 }
252
253 if self.prefix.is_some()
254 || self.name.is_some()
255 || self.into.is_some()
256 || self.strip_option.is_some()
257 || self.each.is_some()
258 {
259 return Some(true);
260 }
261
262 None
263 }
264}
265
266fn field_setter(meta: &Meta) -> darling::Result<FieldLevelSetter> {
269 if let Meta::Path(_) = meta {
272 Ok(FieldLevelSetter {
273 skip: Some(false),
274 ..Default::default()
275 })
276 } else {
277 FieldLevelSetter::from_meta(meta)
278 }
279}
280
281#[derive(Debug, Clone, FromField)]
283#[darling(
284 attributes(builder),
285 forward_attrs(doc, cfg, allow, builder_field_attr, builder_setter_attr),
286 and_then = "Self::resolve"
287)]
288pub struct Field {
289 ident: Option<Ident>,
290 attrs: Vec<syn::Attribute>,
292 ty: syn::Type,
293 pattern: Option<BuilderPattern>,
296 public: Flag,
297 private: Flag,
298 #[darling(rename = "vis")]
303 visibility: Option<syn::Visibility>,
304 #[darling(default, with = "field_setter")]
307 setter: FieldLevelSetter,
308 default: Option<DefaultExpression>,
319 try_setter: Flag,
320 #[darling(default)]
321 field: FieldLevelFieldMeta,
322 sub_builder: Option<darling::util::Override<FieldSubBuilder>>,
324 #[darling(skip)]
325 field_attrs: Vec<Attribute>,
326 #[darling(skip)]
327 setter_attrs: Vec<Attribute>,
328}
329
330impl Field {
331 fn no_visibility_conflicts(&self) -> darling::Result<()> {
332 let mut errors = Error::accumulator();
333 errors.handle(no_visibility_conflict(&self.field));
334 errors.handle(no_visibility_conflict(self));
335 errors.finish()
336 }
337
338 fn resolve(mut self) -> darling::Result<Self> {
343 let mut errors = darling::Error::accumulator();
344
345 if let Field {
349 default: Some(field_default),
350 field:
351 FieldLevelFieldMeta {
352 build: Some(_custom_build),
353 ..
354 },
355 ..
356 } = &self
357 {
358 errors.push(
359 darling::Error::custom(
360 r#"#[builder(default)] and #[builder(field(build="..."))] cannot be used together"#,
361 )
362 .with_span(field_default),
363 );
364 };
365
366 self.resolve_sub_builder_field_type(&mut errors);
367
368 errors.handle(distribute_and_unnest_attrs(
369 &mut self.attrs,
370 &mut [
371 ("builder_field_attr", &mut self.field_attrs),
372 ("builder_setter_attr", &mut self.setter_attrs),
373 ],
374 ));
375
376 errors.finish_with(self)
377 }
378
379 fn resolve_sub_builder_field_type(&mut self, errors: &mut darling::error::Accumulator) {
383 if !(self.sub_builder.is_some() && self.field.builder_type.is_none()) {
384 return;
385 }
386
387 self.field.builder_type = (|| {
388 let ty = &self.ty;
389 let mut out = ty.clone();
390 let p = match &mut out {
391 syn::Type::Path(p) => p,
392 _ => return None,
393 };
394 let last_ident = &mut p.path.segments.last_mut()?.ident;
395 *last_ident = format_ident!("{}Builder", last_ident);
396 Some(out)
397 })()
398 .or_else(|| {
399 errors.push(
400 darling::Error::custom(
401 "field type is not a non-empty path, sub-builder type must be specified",
402 )
403 .with_span(&self.ty),
404 );
405 None
406 });
407 }
408}
409
410fn distribute_and_unnest_attrs(
426 input: &mut Vec<Attribute>,
427 outputs: &mut [(&'static str, &mut Vec<Attribute>)],
428) -> darling::Result<()> {
429 let mut errors = vec![];
430
431 for (name, list) in &*outputs {
432 assert!(list.is_empty(), "Output Vec for '{}' was not empty", name);
433 }
434
435 for attr in input.drain(..) {
436 let destination = outputs
437 .iter_mut()
438 .find(|(ptattr, _)| attr.path.is_ident(ptattr));
439
440 if let Some((_, destination)) = destination {
441 match unnest_from_one_attribute(attr) {
442 Ok(n) => destination.push(n),
443 Err(e) => errors.push(e),
444 }
445 } else {
446 for (_, output) in outputs.iter_mut() {
447 output.push(attr.clone());
448 }
449 }
450 }
451
452 if !errors.is_empty() {
453 return Err(darling::Error::multiple(errors));
454 }
455
456 Ok(())
457}
458
459fn unnest_from_one_attribute(attr: syn::Attribute) -> darling::Result<Attribute> {
460 match &attr.style {
461 syn::AttrStyle::Outer => (),
462 syn::AttrStyle::Inner(bang) => {
463 return Err(darling::Error::unsupported_format(&format!(
464 "{} must be an outer attribute",
465 attr.path
466 .get_ident()
467 .map(Ident::to_string)
468 .unwrap_or_else(|| "Attribute".to_string())
469 ))
470 .with_span(bang));
471 }
472 };
473
474 #[derive(Debug)]
475 struct ContainedAttribute(syn::Attribute);
476 impl syn::parse::Parse for ContainedAttribute {
477 fn parse(input: ParseStream) -> syn::Result<Self> {
478 let content;
480 let paren_token = parenthesized!(content in input);
481 let wrap_span = paren_token.span;
482
483 let pound = Token; let content: TokenStream = content.parse()?;
486 let content = quote_spanned!(wrap_span=> #pound [ #content ]);
487
488 let parser = syn::Attribute::parse_outer;
489 let mut attrs = parser.parse2(content)?.into_iter();
490 let attr = match (attrs.next(), attrs.next()) {
493 (Some(attr), None) => attr,
494 _ => return Err(input.error("expected exactly one attribute")),
495 };
496 Ok(Self(attr))
497 }
498 }
499
500 let ContainedAttribute(attr) = syn::parse2(attr.tokens)?;
501 Ok(attr)
502}
503
504impl Visibility for Field {
505 fn public(&self) -> &Flag {
506 &self.public
507 }
508
509 fn private(&self) -> &Flag {
510 &self.private
511 }
512
513 fn explicit(&self) -> Option<&syn::Visibility> {
514 self.visibility.as_ref()
515 }
516}
517
518#[derive(Debug, Clone, Default, FromMeta)]
522#[darling(default)]
523struct FieldSubBuilder {
524 #[darling(default)]
526 fn_name: Option<Ident>,
527}
528
529fn default_create_empty() -> Ident {
530 Ident::new("create_empty", Span::call_site())
531}
532
533#[derive(Debug, Clone, FromDeriveInput)]
534#[darling(
535 attributes(builder),
536 forward_attrs(cfg, allow, builder_struct_attr, builder_impl_attr),
537 supports(struct_named),
538 and_then = "Self::unnest_attrs"
539)]
540pub struct Options {
541 ident: Ident,
542
543 attrs: Vec<Attribute>,
549
550 #[darling(skip)]
551 struct_attrs: Vec<Attribute>,
552
553 #[darling(skip)]
554 impl_attrs: Vec<Attribute>,
555
556 vis: syn::Visibility,
559
560 generics: Generics,
561
562 name: Option<Ident>,
564
565 #[darling(default)]
566 pattern: BuilderPattern,
567
568 #[darling(default)]
569 build_fn: BuildFn,
570
571 #[darling(default)]
573 derive: PathList,
574
575 custom_constructor: Flag,
576
577 #[darling(default = "default_create_empty")]
580 create_empty: Ident,
581
582 #[darling(default)]
584 setter: StructLevelSetter,
585
586 default: Option<DefaultExpression>,
588
589 public: Flag,
590
591 private: Flag,
592
593 #[darling(rename = "vis")]
597 visibility: Option<syn::Visibility>,
598
599 data: darling::ast::Data<darling::util::Ignored, Field>,
601
602 no_std: Flag,
603
604 try_setter: Flag,
607
608 #[darling(default)]
609 field: StructLevelFieldMeta,
610
611 #[darling(skip, default)]
612 deprecation_notes: DeprecationNotes,
613}
614
615impl Visibility for Options {
616 fn public(&self) -> &Flag {
617 &self.public
618 }
619
620 fn private(&self) -> &Flag {
621 &self.private
622 }
623
624 fn explicit(&self) -> Option<&syn::Visibility> {
625 self.visibility.as_ref()
626 }
627}
628
629impl Options {
630 fn unnest_attrs(mut self) -> darling::Result<Self> {
632 let mut errors = Error::accumulator();
633
634 errors.handle(distribute_and_unnest_attrs(
635 &mut self.attrs,
636 &mut [
637 ("builder_struct_attr", &mut self.struct_attrs),
638 ("builder_impl_attr", &mut self.impl_attrs),
639 ],
640 ));
641
642 errors.handle(no_visibility_conflict(&self.field));
646 errors.handle(no_visibility_conflict(&self.build_fn));
647 self.data
648 .as_ref()
649 .map_struct_fields(|f| errors.handle(f.no_visibility_conflicts()));
650 errors.handle(no_visibility_conflict(&self));
651
652 errors.finish_with(self)
653 }
654}
655
656impl Options {
658 pub fn builder_ident(&self) -> Ident {
659 if let Some(ref custom) = self.name {
660 return custom.clone();
661 }
662
663 format_ident!("{}Builder", self.ident)
664 }
665
666 pub fn builder_error_ident(&self) -> Path {
667 if let Some(existing) = self.build_fn.error.as_ref() {
668 existing.clone()
669 } else if let Some(ref custom) = self.name {
670 format_ident!("{}Error", custom).into()
671 } else {
672 format_ident!("{}BuilderError", self.ident).into()
673 }
674 }
675
676 pub fn builder_vis(&self) -> Cow<syn::Visibility> {
680 self.as_expressed_vis().unwrap_or(Cow::Borrowed(&self.vis))
681 }
682
683 pub fn build_method_vis(&self) -> Cow<syn::Visibility> {
686 self.build_fn
687 .as_expressed_vis()
688 .unwrap_or_else(|| self.builder_vis())
689 }
690
691 pub fn raw_fields(&self) -> Vec<&Field> {
692 self.data
693 .as_ref()
694 .take_struct()
695 .expect("Only structs supported")
696 .fields
697 }
698
699 pub fn requires_clone(&self) -> bool {
702 self.pattern.requires_clone() || self.fields().any(|f| f.pattern().requires_clone())
703 }
704
705 pub fn fields(&self) -> FieldIter {
708 FieldIter(self, self.raw_fields().into_iter())
709 }
710
711 pub fn field_count(&self) -> usize {
712 self.raw_fields().len()
713 }
714}
715
716impl Options {
718 pub fn as_builder(&self) -> Builder {
719 Builder {
720 enabled: true,
721 ident: self.builder_ident(),
722 pattern: self.pattern,
723 derives: &self.derive,
724 struct_attrs: &self.struct_attrs,
725 impl_attrs: &self.impl_attrs,
726 impl_default: !self.custom_constructor.is_present(),
727 create_empty: self.create_empty.clone(),
728 generics: Some(&self.generics),
729 visibility: self.builder_vis(),
730 fields: Vec::with_capacity(self.field_count()),
731 field_initializers: Vec::with_capacity(self.field_count()),
732 functions: Vec::with_capacity(self.field_count()),
733 generate_error: self.build_fn.error.is_none(),
734 must_derive_clone: self.requires_clone(),
735 doc_comment: None,
736 deprecation_notes: Default::default(),
737 std: !self.no_std.is_present(),
738 }
739 }
740
741 pub fn as_build_method(&self) -> BuildMethod {
742 let (_, ty_generics, _) = self.generics.split_for_impl();
743 BuildMethod {
744 enabled: !self.build_fn.skip,
745 ident: &self.build_fn.name,
746 visibility: self.build_method_vis(),
747 pattern: self.pattern,
748 target_ty: &self.ident,
749 target_ty_generics: Some(ty_generics),
750 error_ty: self.builder_error_ident(),
751 initializers: Vec::with_capacity(self.field_count()),
752 doc_comment: None,
753 default_struct: self.default.as_ref(),
754 validate_fn: self.build_fn.validate.as_ref(),
755 }
756 }
757}
758
759pub struct FieldWithDefaults<'a> {
762 parent: &'a Options,
763 field: &'a Field,
764}
765
766impl<'a> FieldWithDefaults<'a> {
769 pub fn setter_enabled(&self) -> bool {
771 self.field
772 .setter
773 .setter_enabled()
774 .or_else(|| self.parent.setter.enabled())
775 .unwrap_or(true)
776 }
777
778 pub fn field_enabled(&self) -> bool {
779 self.field
780 .setter
781 .field_enabled()
782 .or_else(|| self.parent.setter.enabled())
783 .unwrap_or(true)
784 }
785
786 pub fn try_setter(&self) -> bool {
789 self.field.try_setter.is_present() || self.parent.try_setter.is_present()
790 }
791
792 pub fn setter_prefix(&self) -> Option<&Ident> {
795 self.field
796 .setter
797 .prefix
798 .as_ref()
799 .or(self.parent.setter.prefix.as_ref())
800 }
801
802 pub fn setter_ident(&self) -> syn::Ident {
804 if let Some(ref custom) = self.field.setter.name {
805 return custom.clone();
806 }
807
808 let ident = &self.field.ident;
809
810 if let Some(ref prefix) = self.setter_prefix() {
811 return format_ident!("{}_{}", prefix, ident.as_ref().unwrap());
812 }
813
814 ident.clone().unwrap()
815 }
816
817 pub fn setter_into(&self) -> bool {
820 self.field
821 .setter
822 .into
823 .or(self.parent.setter.into)
824 .unwrap_or_default()
825 }
826
827 pub fn setter_strip_option(&self) -> bool {
830 self.field
831 .setter
832 .strip_option
833 .or(self.parent.setter.strip_option)
834 .unwrap_or_default()
835 }
836
837 pub fn setter_vis(&self) -> Cow<syn::Visibility> {
839 self.field
840 .as_expressed_vis()
841 .or_else(|| self.parent.as_expressed_vis())
842 .unwrap_or_else(|| Cow::Owned(syn::parse_quote!(pub)))
843 }
844
845 pub fn field_ident(&self) -> &syn::Ident {
848 self.field
849 .ident
850 .as_ref()
851 .expect("Tuple structs are not supported")
852 }
853
854 pub fn field_vis(&self) -> Cow<syn::Visibility> {
855 self.field
856 .field
857 .as_expressed_vis()
858 .or_else(
859 || {
863 if self.field_enabled() {
864 None
865 } else {
866 Some(Cow::Owned(syn::Visibility::Inherited))
867 }
868 },
869 )
870 .or_else(|| self.parent.field.as_expressed_vis())
871 .unwrap_or(Cow::Owned(syn::Visibility::Inherited))
872 }
873
874 pub fn field_type(&'a self) -> BuilderFieldType<'a> {
875 if !self.field_enabled() {
876 BuilderFieldType::Phantom(&self.field.ty)
877 } else if let Some(custom_ty) = self.field.field.builder_type.as_ref() {
878 BuilderFieldType::Precise(custom_ty)
879 } else {
880 BuilderFieldType::Optional(&self.field.ty)
881 }
882 }
883
884 pub fn conversion(&'a self) -> FieldConversion<'a> {
885 if let Some(block) = &self.field.field.build {
886 FieldConversion::Block(block)
887 } else if let Some(sub) = &self.field.sub_builder {
888 let method = sub
889 .as_ref()
890 .explicit()
891 .and_then(|sub| sub.fn_name.as_ref())
892 .unwrap_or(&self.parent.build_fn.name);
893 FieldConversion::Method(method)
894 } else if self.field.field.builder_type.is_some() {
895 FieldConversion::Move
896 } else {
897 FieldConversion::OptionOrDefault
898 }
899 }
900
901 pub fn pattern(&self) -> BuilderPattern {
902 self.field.pattern.unwrap_or(self.parent.pattern)
903 }
904
905 pub fn use_parent_default(&self) -> bool {
906 self.field.default.is_none() && self.parent.default.is_some()
907 }
908
909 pub fn deprecation_notes(&self) -> &DeprecationNotes {
910 &self.parent.deprecation_notes
911 }
912
913 pub fn sub_accessor(&self) -> bool {
914 match self.pattern() {
915 BuilderPattern::Mutable => self.field.sub_builder.is_some(),
916 BuilderPattern::Owned => false,
917 BuilderPattern::Immutable => false,
918 }
919 }
920}
921
922impl<'a> FieldWithDefaults<'a> {
924 pub fn as_setter(&'a self) -> Setter<'a> {
926 Setter {
927 setter_enabled: self.setter_enabled(),
928 try_setter: self.try_setter(),
929 visibility: self.setter_vis(),
930 pattern: self.pattern(),
931 attrs: &self.field.setter_attrs,
932 ident: self.setter_ident(),
933 field_ident: self.field_ident(),
934 field_type: self.field_type(),
935 generic_into: self.setter_into(),
936 strip_option: self.setter_strip_option(),
937 deprecation_notes: self.deprecation_notes(),
938 each: self.field.setter.each.as_ref(),
939 sub_accessor: self.sub_accessor(),
940 }
941 }
942
943 pub fn as_initializer(&'a self) -> Initializer<'a> {
949 Initializer {
950 field_enabled: self.field_enabled(),
951 field_ident: self.field_ident(),
952 builder_pattern: self.pattern(),
953 default_value: self.field.default.as_ref(),
954 use_default_struct: self.use_parent_default(),
955 conversion: self.conversion(),
956 custom_error_type_span: self
957 .parent
958 .build_fn
959 .error
960 .as_ref()
961 .map(|err_ty| err_ty.span()),
962 }
963 }
964
965 pub fn as_builder_field(&'a self) -> BuilderField<'a> {
966 BuilderField {
967 field_ident: self.field_ident(),
968 field_type: self.field_type(),
969 field_visibility: self.field_vis(),
970 attrs: &self.field.field_attrs,
971 }
972 }
973}
974
975pub struct FieldIter<'a>(&'a Options, IntoIter<&'a Field>);
976
977impl<'a> Iterator for FieldIter<'a> {
978 type Item = FieldWithDefaults<'a>;
979
980 fn next(&mut self) -> Option<Self::Item> {
981 self.1.next().map(|field| FieldWithDefaults {
982 parent: self.0,
983 field,
984 })
985 }
986}