1 | use std::{borrow::Cow, vec::IntoIter}; |
2 | |
3 | use crate::BuildMethod; |
4 | |
5 | use darling::util::{Flag, PathList}; |
6 | use darling::{self, Error, FromMeta}; |
7 | use proc_macro2::{Span, TokenStream}; |
8 | use syn::parse::{ParseStream, Parser}; |
9 | use syn::Meta; |
10 | use syn::{self, spanned::Spanned, Attribute, Generics, Ident, Path}; |
11 | |
12 | use crate::{ |
13 | BlockContents, Builder, BuilderField, BuilderFieldType, BuilderPattern, DefaultExpression, |
14 | DeprecationNotes, Each, FieldConversion, Initializer, Setter, |
15 | }; |
16 | |
17 | /// `derive_builder` uses separate sibling keywords to represent |
18 | /// mutually-exclusive visibility states. This trait requires implementers to |
19 | /// expose those property values and provides a method to compute any explicit visibility |
20 | /// bounds. |
21 | trait Visibility { |
22 | fn public(&self) -> &Flag; |
23 | fn private(&self) -> &Flag; |
24 | fn explicit(&self) -> Option<&syn::Visibility>; |
25 | |
26 | /// Get the explicitly-expressed visibility preference from the attribute. |
27 | /// This returns `None` if the input didn't include either keyword. |
28 | /// |
29 | /// # Panics |
30 | /// This method panics if the input specifies both `public` and `private`. |
31 | 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 | |
50 | fn no_visibility_conflict<T: Visibility>(v: &T) -> darling::Result<()> { |
51 | let declares_public: bool = v.public().is_present(); |
52 | let declares_private: bool = v.private().is_present(); |
53 | if let Some(vis: &Visibility) = 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(node: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(node:v.public()), |
66 | ) |
67 | } else { |
68 | Ok(()) |
69 | } |
70 | } |
71 | |
72 | /// Options for the `build_fn` property in struct-level builder options. |
73 | /// There is no inheritance for these settings from struct-level to field-level, |
74 | /// so we don't bother using `Option` for values in this struct. |
75 | #[derive (Debug, Clone, FromMeta)] |
76 | #[darling(default)] |
77 | pub struct BuildFn { |
78 | skip: bool, |
79 | name: Ident, |
80 | validate: Option<Path>, |
81 | public: Flag, |
82 | private: Flag, |
83 | vis: Option<syn::Visibility>, |
84 | /// The path to an existing error type that the build method should return. |
85 | /// |
86 | /// Setting this will prevent `derive_builder` from generating an error type for the build |
87 | /// method. |
88 | /// |
89 | /// # Type Bounds |
90 | /// This type's bounds depend on other settings of the builder. |
91 | /// |
92 | /// * If uninitialized fields cause `build()` to fail, then this type |
93 | /// must `impl From<UninitializedFieldError>`. Uninitialized fields do not cause errors |
94 | /// when default values are provided for every field or at the struct level. |
95 | /// * If `validate` is specified, then this type must provide a conversion from the specified |
96 | /// function's error type. |
97 | error: Option<Path>, |
98 | } |
99 | |
100 | impl Default for BuildFn { |
101 | fn default() -> Self { |
102 | BuildFn { |
103 | skip: false, |
104 | name: Ident::new(string:"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 | |
114 | impl 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 | /// Contents of the `field` meta in `builder` attributes at the struct level. |
129 | #[derive (Debug, Clone, Default, FromMeta)] |
130 | pub struct StructLevelFieldMeta { |
131 | public: Flag, |
132 | private: Flag, |
133 | vis: Option<syn::Visibility>, |
134 | } |
135 | |
136 | impl 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 | /// Contents of the `field` meta in `builder` attributes at the field level. |
151 | // |
152 | // This is a superset of the attributes permitted in `field` at the struct level. |
153 | // Perhaps in the future we will be able to use `#[darling(flatten)]`, but |
154 | // that does not exist right now: https://github.com/TedDriggs/darling/issues/146 |
155 | #[derive (Debug, Clone, Default, FromMeta)] |
156 | pub struct FieldLevelFieldMeta { |
157 | public: Flag, |
158 | private: Flag, |
159 | vis: Option<syn::Visibility>, |
160 | /// Custom builder field type |
161 | #[darling(rename = "type" )] |
162 | builder_type: Option<syn::Type>, |
163 | /// Custom builder field method, for making target struct field value |
164 | build: Option<BlockContents>, |
165 | } |
166 | |
167 | impl 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)] |
182 | pub struct StructLevelSetter { |
183 | prefix: Option<Ident>, |
184 | into: Option<bool>, |
185 | strip_option: Option<bool>, |
186 | skip: Option<bool>, |
187 | } |
188 | |
189 | impl StructLevelSetter { |
190 | /// Check if setters are explicitly enabled or disabled at |
191 | /// the struct level. |
192 | pub fn enabled(&self) -> Option<bool> { |
193 | self.skip.map(|x: bool| !x) |
194 | } |
195 | } |
196 | |
197 | /// Create `Each` from an attribute's `Meta`. |
198 | /// |
199 | /// Two formats are supported: |
200 | /// |
201 | /// * `each = "..."`, which provides the name of the `each` setter and otherwise uses default values |
202 | /// * `each(name = "...")`, which allows setting additional options on the `each` setter |
203 | fn parse_each(meta: &Meta) -> darling::Result<Option<Each>> { |
204 | if let Meta::NameValue(mnv: &MetaNameValue) = meta { |
205 | if let syn::Lit::Str(v: &LitStr) = &mnv.lit { |
206 | v.parse::<Ident>() |
207 | .map(Each::from) |
208 | .map(Some) |
209 | .map_err(|_| darling::Error::unknown_value(&v.value()).with_span(node: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 | /// The `setter` meta item on fields in the input type. |
219 | /// Unlike the `setter` meta item at the struct level, this allows specific |
220 | /// name overrides. |
221 | #[derive (Debug, Clone, Default, FromMeta)] |
222 | pub 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 | |
233 | impl FieldLevelSetter { |
234 | /// Get whether the setter should be emitted. The rules are the same as |
235 | /// for `field_enabled`, except we only skip the setter if `setter(custom)` is present. |
236 | 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 | /// Get whether or not this field-level setter indicates a setter and |
245 | /// field should be emitted. The setter shorthand rules are that the |
246 | /// presence of a `setter` with _any_ properties set forces the setter |
247 | /// to be emitted. |
248 | 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 | |
266 | /// `derive_builder` allows the calling code to use `setter` as a word to enable |
267 | /// setters when they've been disabled at the struct level. |
268 | fn field_setter(meta: &Meta) -> darling::Result<FieldLevelSetter> { |
269 | // it doesn't matter what the path is; the fact that this function |
270 | // has been called means that a valueless path is the shorthand case. |
271 | 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 | /// Data extracted from the fields of the input struct. |
282 | #[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 | )] |
288 | pub struct Field { |
289 | ident: Option<Ident>, |
290 | /// Raw input attributes, for consumption by Field::unnest_attrs. Do not use elsewhere. |
291 | attrs: Vec<syn::Attribute>, |
292 | ty: syn::Type, |
293 | /// Field-level override for builder pattern. |
294 | /// Note that setting this may force the builder to derive `Clone`. |
295 | pattern: Option<BuilderPattern>, |
296 | public: Flag, |
297 | private: Flag, |
298 | /// Declared visibility for the field in the builder, e.g. `#[builder(vis = "...")]`. |
299 | /// |
300 | /// This cannot be named `vis` or `darling` would put the deriving field's visibility into the |
301 | /// field instead. |
302 | #[darling(rename = "vis" )] |
303 | visibility: Option<syn::Visibility>, |
304 | // See the documentation for `FieldSetterMeta` to understand how `darling` |
305 | // is interpreting this field. |
306 | #[darling(default, with = "field_setter" )] |
307 | setter: FieldLevelSetter, |
308 | /// The value for this field if the setter is never invoked. |
309 | /// |
310 | /// A field can get its default one of three ways: |
311 | /// |
312 | /// 1. An explicit `default = "..."` expression |
313 | /// 2. An explicit `default` word, in which case the field type's `Default::default()` |
314 | /// value is used |
315 | /// 3. Inherited from the field's value in the struct's `default` value. |
316 | /// |
317 | /// This property only captures the first two, the third is computed in `FieldWithDefaults`. |
318 | default: Option<DefaultExpression>, |
319 | try_setter: Flag, |
320 | #[darling(default)] |
321 | field: FieldLevelFieldMeta, |
322 | #[darling(skip)] |
323 | field_attrs: Vec<Attribute>, |
324 | #[darling(skip)] |
325 | setter_attrs: Vec<Attribute>, |
326 | } |
327 | |
328 | impl Field { |
329 | fn no_visibility_conflicts(&self) -> darling::Result<()> { |
330 | let mut errors = Error::accumulator(); |
331 | errors.handle(no_visibility_conflict(&self.field)); |
332 | errors.handle(no_visibility_conflict(self)); |
333 | errors.finish() |
334 | } |
335 | |
336 | /// Resolve and check (post-parsing) options which come from multiple darling options |
337 | /// |
338 | /// * Check that we don't have a custom field type or builder *and* a default value |
339 | /// * Populate `self.field_attrs` and `self.setter_attrs` by draining `self.attrs` |
340 | fn resolve(mut self) -> darling::Result<Self> { |
341 | let mut errors = darling::Error::accumulator(); |
342 | |
343 | // `default` can be preempted by properties in `field`. Silently ignoring a |
344 | // `default` could cause the direct user of `derive_builder` to see unexpected |
345 | // behavior from the builder, so instead we require that the deriving struct |
346 | // not pass any ignored instructions. |
347 | if let Field { |
348 | default: Some(field_default), |
349 | .. |
350 | } = &self |
351 | { |
352 | // `field.build` is stronger than `default`, as it contains both instructions on how to |
353 | // deal with a missing value and conversions to do on the value during target type |
354 | // construction. |
355 | if self.field.build.is_some() { |
356 | errors.push( |
357 | darling::Error::custom( |
358 | r#"#[builder(default)] and #[builder(field(build="..."))] cannot be used together"# , |
359 | ) |
360 | .with_span(field_default), |
361 | ); |
362 | } |
363 | |
364 | // `field.type` being set means `default` will not be used, since we don't know how |
365 | // to check a custom field type for the absence of a value and therefore we'll never |
366 | // know that we should use the `default` value. |
367 | if self.field.builder_type.is_some() { |
368 | errors.push( |
369 | darling::Error::custom( |
370 | r#"#[builder(default)] and #[builder(field(type="..."))] cannot be used together"# , |
371 | ) |
372 | .with_span(field_default) |
373 | ) |
374 | } |
375 | }; |
376 | |
377 | errors.handle(distribute_and_unnest_attrs( |
378 | &mut self.attrs, |
379 | &mut [ |
380 | ("builder_field_attr" , &mut self.field_attrs), |
381 | ("builder_setter_attr" , &mut self.setter_attrs), |
382 | ], |
383 | )); |
384 | |
385 | errors.finish_with(self) |
386 | } |
387 | } |
388 | |
389 | /// Divide a list of attributes into multiple partially-overlapping output lists. |
390 | /// |
391 | /// Some attributes from the macro input will be added to the output in multiple places; |
392 | /// for example, a `cfg` attribute must be replicated to both the struct and its impl block or |
393 | /// the resulting code will not compile. |
394 | /// |
395 | /// Other attributes are scoped to a specific output by their path, e.g. `builder_field_attr`. |
396 | /// These attributes will only appear in one output list, but need that outer path removed. |
397 | /// |
398 | /// For performance reasons, we want to do this in one pass through the list instead of |
399 | /// first distributing and then iterating through each of the output lists. |
400 | /// |
401 | /// Each item in `outputs` contains the attribute name unique to that output, and the `Vec` where all attributes for that output should be inserted. |
402 | /// Attributes whose path matches any value in `outputs` will be added only to the first matching one, and will be "unnested". |
403 | /// Other attributes are not unnested, and simply copied for each decoratee. |
404 | fn distribute_and_unnest_attrs( |
405 | input: &mut Vec<Attribute>, |
406 | outputs: &mut [(&'static str, &mut Vec<Attribute>)], |
407 | ) -> darling::Result<()> { |
408 | let mut errors = vec![]; |
409 | |
410 | for (name, list) in &*outputs { |
411 | assert!(list.is_empty(), "Output Vec for ' {}' was not empty" , name); |
412 | } |
413 | |
414 | for attr in input.drain(..) { |
415 | let destination = outputs |
416 | .iter_mut() |
417 | .find(|(ptattr, _)| attr.path.is_ident(ptattr)); |
418 | |
419 | if let Some((_, destination)) = destination { |
420 | match unnest_from_one_attribute(attr) { |
421 | Ok(n) => destination.push(n), |
422 | Err(e) => errors.push(e), |
423 | } |
424 | } else { |
425 | for (_, output) in outputs.iter_mut() { |
426 | output.push(attr.clone()); |
427 | } |
428 | } |
429 | } |
430 | |
431 | if !errors.is_empty() { |
432 | return Err(darling::Error::multiple(errors)); |
433 | } |
434 | |
435 | Ok(()) |
436 | } |
437 | |
438 | fn unnest_from_one_attribute(attr: syn::Attribute) -> darling::Result<Attribute> { |
439 | match &attr.style { |
440 | syn::AttrStyle::Outer => (), |
441 | syn::AttrStyle::Inner(bang) => { |
442 | return Err(darling::Error::unsupported_format(&format!( |
443 | " {} must be an outer attribute" , |
444 | attr.path |
445 | .get_ident() |
446 | .map(Ident::to_string) |
447 | .unwrap_or_else(|| "Attribute" .to_string()) |
448 | )) |
449 | .with_span(bang)); |
450 | } |
451 | }; |
452 | |
453 | #[derive (Debug)] |
454 | struct ContainedAttribute(syn::Attribute); |
455 | impl syn::parse::Parse for ContainedAttribute { |
456 | fn parse(input: ParseStream) -> syn::Result<Self> { |
457 | // Strip parentheses, and save the span of the parenthesis token |
458 | let content; |
459 | let paren_token = parenthesized!(content in input); |
460 | let wrap_span = paren_token.span; |
461 | |
462 | // Wrap up in #[ ] instead. |
463 | let pound = Token![#](wrap_span); // We can't write a literal # inside quote |
464 | let content: TokenStream = content.parse()?; |
465 | let content = quote_spanned!(wrap_span=> #pound [ #content ]); |
466 | |
467 | let parser = syn::Attribute::parse_outer; |
468 | let mut attrs = parser.parse2(content)?.into_iter(); |
469 | // TryFrom for Array not available in Rust 1.40 |
470 | // We think this error can never actually happen, since `#[...]` ought to make just one Attribute |
471 | let attr = match (attrs.next(), attrs.next()) { |
472 | (Some(attr), None) => attr, |
473 | _ => return Err(input.error("expected exactly one attribute" )), |
474 | }; |
475 | Ok(Self(attr)) |
476 | } |
477 | } |
478 | |
479 | let ContainedAttribute(attr) = syn::parse2(attr.tokens)?; |
480 | Ok(attr) |
481 | } |
482 | |
483 | impl Visibility for Field { |
484 | fn public(&self) -> &Flag { |
485 | &self.public |
486 | } |
487 | |
488 | fn private(&self) -> &Flag { |
489 | &self.private |
490 | } |
491 | |
492 | fn explicit(&self) -> Option<&syn::Visibility> { |
493 | self.visibility.as_ref() |
494 | } |
495 | } |
496 | |
497 | fn default_crate_root() -> Path { |
498 | parse_quote!(::derive_builder) |
499 | } |
500 | |
501 | fn default_create_empty() -> Ident { |
502 | Ident::new(string:"create_empty" , Span::call_site()) |
503 | } |
504 | |
505 | #[derive (Debug, Clone, FromDeriveInput)] |
506 | #[darling( |
507 | attributes(builder), |
508 | forward_attrs(cfg, allow, builder_struct_attr, builder_impl_attr), |
509 | supports(struct_named), |
510 | and_then = "Self::unnest_attrs" |
511 | )] |
512 | pub struct Options { |
513 | ident: Ident, |
514 | |
515 | /// DO NOT USE. |
516 | /// |
517 | /// Initial receiver for forwarded attributes from the struct; these are split |
518 | /// into `Options::struct_attrs` and `Options::impl_attrs` before `FromDeriveInput` |
519 | /// returns. |
520 | attrs: Vec<Attribute>, |
521 | |
522 | #[darling(skip)] |
523 | struct_attrs: Vec<Attribute>, |
524 | |
525 | #[darling(skip)] |
526 | impl_attrs: Vec<Attribute>, |
527 | |
528 | /// The visibility of the deriving struct. Do not confuse this with `#[builder(vis = "...")]`, |
529 | /// which is received by `Options::visibility`. |
530 | vis: syn::Visibility, |
531 | |
532 | generics: Generics, |
533 | |
534 | /// The name of the generated builder. Defaults to `#{ident}Builder`. |
535 | name: Option<Ident>, |
536 | |
537 | /// The path to the root of the derive_builder crate used in generated |
538 | /// code. |
539 | #[darling(rename = "crate" , default = "default_crate_root" )] |
540 | crate_root: Path, |
541 | |
542 | #[darling(default)] |
543 | pattern: BuilderPattern, |
544 | |
545 | #[darling(default)] |
546 | build_fn: BuildFn, |
547 | |
548 | /// Additional traits to derive on the builder. |
549 | #[darling(default)] |
550 | derive: PathList, |
551 | |
552 | custom_constructor: Flag, |
553 | |
554 | /// The ident of the inherent method which takes no arguments and returns |
555 | /// an instance of the builder with all fields empty. |
556 | #[darling(default = "default_create_empty" )] |
557 | create_empty: Ident, |
558 | |
559 | /// Setter options applied to all field setters in the struct. |
560 | #[darling(default)] |
561 | setter: StructLevelSetter, |
562 | |
563 | /// Struct-level value to use in place of any unfilled fields |
564 | default: Option<DefaultExpression>, |
565 | |
566 | public: Flag, |
567 | |
568 | private: Flag, |
569 | |
570 | /// Desired visibility of the builder struct. |
571 | /// |
572 | /// Do not confuse this with `Options::vis`, which is the visibility of the deriving struct. |
573 | #[darling(rename = "vis" )] |
574 | visibility: Option<syn::Visibility>, |
575 | |
576 | /// The parsed body of the derived struct. |
577 | data: darling::ast::Data<darling::util::Ignored, Field>, |
578 | |
579 | no_std: Flag, |
580 | |
581 | /// When present, emit additional fallible setters alongside each regular |
582 | /// setter. |
583 | try_setter: Flag, |
584 | |
585 | #[darling(default)] |
586 | field: StructLevelFieldMeta, |
587 | |
588 | #[darling(skip, default)] |
589 | deprecation_notes: DeprecationNotes, |
590 | } |
591 | |
592 | impl Visibility for Options { |
593 | fn public(&self) -> &Flag { |
594 | &self.public |
595 | } |
596 | |
597 | fn private(&self) -> &Flag { |
598 | &self.private |
599 | } |
600 | |
601 | fn explicit(&self) -> Option<&syn::Visibility> { |
602 | self.visibility.as_ref() |
603 | } |
604 | } |
605 | |
606 | impl Options { |
607 | /// Populate `self.struct_attrs` and `self.impl_attrs` by draining `self.attrs` |
608 | fn unnest_attrs(mut self) -> darling::Result<Self> { |
609 | let mut errors = Error::accumulator(); |
610 | |
611 | errors.handle(distribute_and_unnest_attrs( |
612 | &mut self.attrs, |
613 | &mut [ |
614 | ("builder_struct_attr" , &mut self.struct_attrs), |
615 | ("builder_impl_attr" , &mut self.impl_attrs), |
616 | ], |
617 | )); |
618 | |
619 | // Check for conflicting visibility declarations. These cannot be pushed |
620 | // down into `FieldMeta` et al because of the call to `no_visibility_conflict(&self)`, |
621 | // as all sub-fields must be valid for this `Options` function to run. |
622 | errors.handle(no_visibility_conflict(&self.field)); |
623 | errors.handle(no_visibility_conflict(&self.build_fn)); |
624 | self.data |
625 | .as_ref() |
626 | .map_struct_fields(|f| errors.handle(f.no_visibility_conflicts())); |
627 | errors.handle(no_visibility_conflict(&self)); |
628 | |
629 | errors.finish_with(self) |
630 | } |
631 | } |
632 | |
633 | /// Accessors for parsed properties. |
634 | impl Options { |
635 | pub fn builder_ident(&self) -> Ident { |
636 | if let Some(ref custom) = self.name { |
637 | return custom.clone(); |
638 | } |
639 | |
640 | format_ident!(" {}Builder" , self.ident) |
641 | } |
642 | |
643 | pub fn builder_error_ident(&self) -> Path { |
644 | if let Some(existing) = self.build_fn.error.as_ref() { |
645 | existing.clone() |
646 | } else if let Some(ref custom) = self.name { |
647 | format_ident!(" {}Error" , custom).into() |
648 | } else { |
649 | format_ident!(" {}BuilderError" , self.ident).into() |
650 | } |
651 | } |
652 | |
653 | /// The visibility of the builder struct. |
654 | /// If a visibility was declared in attributes, that will be used; |
655 | /// otherwise the struct's own visibility will be used. |
656 | pub fn builder_vis(&self) -> Cow<syn::Visibility> { |
657 | self.as_expressed_vis().unwrap_or(Cow::Borrowed(&self.vis)) |
658 | } |
659 | |
660 | /// Get the visibility of the emitted `build` method. |
661 | /// This defaults to the visibility of the parent builder, but can be overridden. |
662 | pub fn build_method_vis(&self) -> Cow<syn::Visibility> { |
663 | self.build_fn |
664 | .as_expressed_vis() |
665 | .unwrap_or_else(|| self.builder_vis()) |
666 | } |
667 | |
668 | pub fn raw_fields(&self) -> Vec<&Field> { |
669 | self.data |
670 | .as_ref() |
671 | .take_struct() |
672 | .expect("Only structs supported" ) |
673 | .fields |
674 | } |
675 | |
676 | /// A builder requires `Clone` to be derived if its build method or any of its setters |
677 | /// use the mutable or immutable pattern. |
678 | pub fn requires_clone(&self) -> bool { |
679 | self.pattern.requires_clone() || self.fields().any(|f| f.pattern().requires_clone()) |
680 | } |
681 | |
682 | /// Get an iterator over the input struct's fields which pulls fallback |
683 | /// values from struct-level settings. |
684 | pub fn fields(&self) -> FieldIter { |
685 | FieldIter(self, self.raw_fields().into_iter()) |
686 | } |
687 | |
688 | pub fn field_count(&self) -> usize { |
689 | self.raw_fields().len() |
690 | } |
691 | } |
692 | |
693 | /// Converters to codegen structs |
694 | impl Options { |
695 | pub fn as_builder(&self) -> Builder { |
696 | Builder { |
697 | crate_root: &self.crate_root, |
698 | enabled: true, |
699 | ident: self.builder_ident(), |
700 | pattern: self.pattern, |
701 | derives: &self.derive, |
702 | struct_attrs: &self.struct_attrs, |
703 | impl_attrs: &self.impl_attrs, |
704 | impl_default: !self.custom_constructor.is_present(), |
705 | create_empty: self.create_empty.clone(), |
706 | generics: Some(&self.generics), |
707 | visibility: self.builder_vis(), |
708 | fields: Vec::with_capacity(self.field_count()), |
709 | field_initializers: Vec::with_capacity(self.field_count()), |
710 | functions: Vec::with_capacity(self.field_count()), |
711 | generate_error: self.build_fn.error.is_none(), |
712 | must_derive_clone: self.requires_clone(), |
713 | doc_comment: None, |
714 | deprecation_notes: Default::default(), |
715 | std: !self.no_std.is_present(), |
716 | } |
717 | } |
718 | |
719 | pub fn as_build_method(&self) -> BuildMethod { |
720 | let (_, ty_generics, _) = self.generics.split_for_impl(); |
721 | BuildMethod { |
722 | crate_root: &self.crate_root, |
723 | enabled: !self.build_fn.skip, |
724 | ident: &self.build_fn.name, |
725 | visibility: self.build_method_vis(), |
726 | pattern: self.pattern, |
727 | target_ty: &self.ident, |
728 | target_ty_generics: Some(ty_generics), |
729 | error_ty: self.builder_error_ident(), |
730 | initializers: Vec::with_capacity(self.field_count()), |
731 | doc_comment: None, |
732 | default_struct: self.default.as_ref(), |
733 | validate_fn: self.build_fn.validate.as_ref(), |
734 | } |
735 | } |
736 | } |
737 | |
738 | /// Accessor for field data which can pull through options from the parent |
739 | /// struct. |
740 | pub struct FieldWithDefaults<'a> { |
741 | parent: &'a Options, |
742 | field: &'a Field, |
743 | } |
744 | |
745 | /// Accessors for parsed properties, with transparent pull-through from the |
746 | /// parent struct's configuration. |
747 | impl<'a> FieldWithDefaults<'a> { |
748 | /// Check if this field should emit a setter. |
749 | pub fn setter_enabled(&self) -> bool { |
750 | self.field |
751 | .setter |
752 | .setter_enabled() |
753 | .or_else(|| self.parent.setter.enabled()) |
754 | .unwrap_or(true) |
755 | } |
756 | |
757 | pub fn field_enabled(&self) -> bool { |
758 | self.field |
759 | .setter |
760 | .field_enabled() |
761 | .or_else(|| self.parent.setter.enabled()) |
762 | .unwrap_or(true) |
763 | } |
764 | |
765 | /// Check if this field should emit a fallible setter. |
766 | /// This depends on the `TryFrom` trait, which hasn't yet stabilized. |
767 | pub fn try_setter(&self) -> bool { |
768 | self.field.try_setter.is_present() || self.parent.try_setter.is_present() |
769 | } |
770 | |
771 | /// Get the prefix that should be applied to the field name to produce |
772 | /// the setter ident, if any. |
773 | pub fn setter_prefix(&self) -> Option<&Ident> { |
774 | self.field |
775 | .setter |
776 | .prefix |
777 | .as_ref() |
778 | .or(self.parent.setter.prefix.as_ref()) |
779 | } |
780 | |
781 | /// Get the ident of the emitted setter method |
782 | pub fn setter_ident(&self) -> syn::Ident { |
783 | if let Some(ref custom) = self.field.setter.name { |
784 | return custom.clone(); |
785 | } |
786 | |
787 | let ident = &self.field.ident; |
788 | |
789 | if let Some(ref prefix) = self.setter_prefix() { |
790 | return format_ident!(" {}_ {}" , prefix, ident.as_ref().unwrap()); |
791 | } |
792 | |
793 | ident.clone().unwrap() |
794 | } |
795 | |
796 | /// Checks if the emitted setter should be generic over types that impl |
797 | /// `Into<FieldType>`. |
798 | pub fn setter_into(&self) -> bool { |
799 | self.field |
800 | .setter |
801 | .into |
802 | .or(self.parent.setter.into) |
803 | .unwrap_or_default() |
804 | } |
805 | |
806 | /// Checks if the emitted setter should strip the wrapper Option over types that impl |
807 | /// `Option<FieldType>`. |
808 | pub fn setter_strip_option(&self) -> bool { |
809 | self.field |
810 | .setter |
811 | .strip_option |
812 | .or(self.parent.setter.strip_option) |
813 | .unwrap_or_default() |
814 | } |
815 | |
816 | /// Get the visibility of the emitted setter, if there will be one. |
817 | pub fn setter_vis(&self) -> Cow<syn::Visibility> { |
818 | self.field |
819 | .as_expressed_vis() |
820 | .or_else(|| self.parent.as_expressed_vis()) |
821 | .unwrap_or_else(|| Cow::Owned(syn::parse_quote!(pub))) |
822 | } |
823 | |
824 | /// Get the ident of the input field. This is also used as the ident of the |
825 | /// emitted field. |
826 | pub fn field_ident(&self) -> &syn::Ident { |
827 | self.field |
828 | .ident |
829 | .as_ref() |
830 | .expect("Tuple structs are not supported" ) |
831 | } |
832 | |
833 | pub fn field_vis(&self) -> Cow<syn::Visibility> { |
834 | self.field |
835 | .field |
836 | .as_expressed_vis() |
837 | .or_else( |
838 | // Disabled fields become a PhantomData in the builder. We make that field |
839 | // non-public, even if the rest of the builder is public, since this field is just |
840 | // there to make sure the struct's generics are properly handled. |
841 | || { |
842 | if self.field_enabled() { |
843 | None |
844 | } else { |
845 | Some(Cow::Owned(syn::Visibility::Inherited)) |
846 | } |
847 | }, |
848 | ) |
849 | .or_else(|| self.parent.field.as_expressed_vis()) |
850 | .unwrap_or(Cow::Owned(syn::Visibility::Inherited)) |
851 | } |
852 | |
853 | pub fn field_type(&'a self) -> BuilderFieldType<'a> { |
854 | if !self.field_enabled() { |
855 | BuilderFieldType::Phantom(&self.field.ty) |
856 | } else if let Some(custom_ty) = self.field.field.builder_type.as_ref() { |
857 | BuilderFieldType::Precise(custom_ty) |
858 | } else { |
859 | BuilderFieldType::Optional(&self.field.ty) |
860 | } |
861 | } |
862 | |
863 | pub fn conversion(&'a self) -> FieldConversion<'a> { |
864 | match (&self.field.field.builder_type, &self.field.field.build) { |
865 | (_, Some(block)) => FieldConversion::Block(block), |
866 | (Some(_), None) => FieldConversion::Move, |
867 | (None, None) => FieldConversion::OptionOrDefault, |
868 | } |
869 | } |
870 | |
871 | pub fn pattern(&self) -> BuilderPattern { |
872 | self.field.pattern.unwrap_or(self.parent.pattern) |
873 | } |
874 | |
875 | pub fn use_parent_default(&self) -> bool { |
876 | self.field.default.is_none() && self.parent.default.is_some() |
877 | } |
878 | |
879 | pub fn deprecation_notes(&self) -> &DeprecationNotes { |
880 | &self.parent.deprecation_notes |
881 | } |
882 | } |
883 | |
884 | /// Converters to codegen structs |
885 | impl<'a> FieldWithDefaults<'a> { |
886 | /// Returns a `Setter` according to the options. |
887 | pub fn as_setter(&'a self) -> Setter<'a> { |
888 | Setter { |
889 | crate_root: &self.parent.crate_root, |
890 | setter_enabled: self.setter_enabled(), |
891 | try_setter: self.try_setter(), |
892 | visibility: self.setter_vis(), |
893 | pattern: self.pattern(), |
894 | attrs: &self.field.setter_attrs, |
895 | ident: self.setter_ident(), |
896 | field_ident: self.field_ident(), |
897 | field_type: self.field_type(), |
898 | generic_into: self.setter_into(), |
899 | strip_option: self.setter_strip_option(), |
900 | deprecation_notes: self.deprecation_notes(), |
901 | each: self.field.setter.each.as_ref(), |
902 | } |
903 | } |
904 | |
905 | /// Returns an `Initializer` according to the options. |
906 | /// |
907 | /// # Panics |
908 | /// |
909 | /// if `default_expression` can not be parsed as `Block`. |
910 | pub fn as_initializer(&'a self) -> Initializer<'a> { |
911 | Initializer { |
912 | crate_root: &self.parent.crate_root, |
913 | field_enabled: self.field_enabled(), |
914 | field_ident: self.field_ident(), |
915 | builder_pattern: self.pattern(), |
916 | default_value: self.field.default.as_ref(), |
917 | use_default_struct: self.use_parent_default(), |
918 | conversion: self.conversion(), |
919 | custom_error_type_span: self |
920 | .parent |
921 | .build_fn |
922 | .error |
923 | .as_ref() |
924 | .map(|err_ty| err_ty.span()), |
925 | } |
926 | } |
927 | |
928 | pub fn as_builder_field(&'a self) -> BuilderField<'a> { |
929 | BuilderField { |
930 | crate_root: &self.parent.crate_root, |
931 | field_ident: self.field_ident(), |
932 | field_type: self.field_type(), |
933 | field_visibility: self.field_vis(), |
934 | attrs: &self.field.field_attrs, |
935 | } |
936 | } |
937 | } |
938 | |
939 | pub struct FieldIter<'a>(&'a Options, IntoIter<&'a Field>); |
940 | |
941 | impl<'a> Iterator for FieldIter<'a> { |
942 | type Item = FieldWithDefaults<'a>; |
943 | |
944 | fn next(&mut self) -> Option<Self::Item> { |
945 | self.1.next().map(|field: &Field| FieldWithDefaults { |
946 | parent: self.0, |
947 | field, |
948 | }) |
949 | } |
950 | } |
951 | |