1 | //! Internal helper library for the `derive_builder` crate. |
2 | //! |
3 | //! **Important Note**: |
4 | //! |
5 | //! * You are probably looking for the [`derive_builder`] crate, |
6 | //! which wraps this crate and is much more ergonomic to use. |
7 | //! |
8 | //! ## Purpose |
9 | //! |
10 | //! This is an internal helper library of [`derive_builder`], which allows for |
11 | //! all the logic of builder creation to be decoupled from the proc-macro entry |
12 | //! point. |
13 | //! |
14 | //! |
15 | //! [`derive_builder`]: https://!crates.io/crates/derive_builder |
16 | //! [`derive_builder_core`]: https://!crates.io/crates/derive_builder_core |
17 | |
18 | #![deny (warnings, missing_docs)] |
19 | #![cfg_attr (test, recursion_limit = "100" )] |
20 | |
21 | #[macro_use ] |
22 | extern crate darling; |
23 | |
24 | extern crate proc_macro; |
25 | extern crate proc_macro2; |
26 | #[macro_use ] |
27 | extern crate syn; |
28 | #[macro_use ] |
29 | extern crate quote; |
30 | #[cfg (test)] |
31 | #[macro_use ] |
32 | extern crate pretty_assertions; |
33 | |
34 | mod block; |
35 | mod build_method; |
36 | mod builder; |
37 | mod builder_field; |
38 | mod change_span; |
39 | mod default_expression; |
40 | mod deprecation_notes; |
41 | mod doc_comment; |
42 | mod initializer; |
43 | mod macro_options; |
44 | mod options; |
45 | mod setter; |
46 | |
47 | pub(crate) use block::BlockContents; |
48 | pub(crate) use build_method::BuildMethod; |
49 | pub(crate) use builder::Builder; |
50 | pub(crate) use builder_field::{BuilderField, BuilderFieldType}; |
51 | pub(crate) use change_span::change_span; |
52 | use darling::FromDeriveInput; |
53 | pub(crate) use default_expression::DefaultExpression; |
54 | pub(crate) use deprecation_notes::DeprecationNotes; |
55 | pub(crate) use doc_comment::doc_comment_from; |
56 | pub(crate) use initializer::{FieldConversion, Initializer}; |
57 | pub(crate) use options::{BuilderPattern, Each}; |
58 | pub(crate) use setter::Setter; |
59 | |
60 | const DEFAULT_STRUCT_NAME: &str = "__default" ; |
61 | |
62 | /// Derive a builder for a struct |
63 | pub fn builder_for_struct(ast: syn::DeriveInput) -> proc_macro2::TokenStream { |
64 | let opts = match macro_options::Options::from_derive_input(&ast) { |
65 | Ok(val) => val, |
66 | Err(err) => { |
67 | return err.write_errors(); |
68 | } |
69 | }; |
70 | |
71 | let mut builder = opts.as_builder(); |
72 | let mut build_fn = opts.as_build_method(); |
73 | |
74 | builder.doc_comment(format!( |
75 | include_str!("doc_tpl/builder_struct.md" ), |
76 | struct_name = ast.ident |
77 | )); |
78 | build_fn.doc_comment(format!( |
79 | include_str!("doc_tpl/builder_method.md" ), |
80 | struct_name = ast.ident |
81 | )); |
82 | |
83 | for field in opts.fields() { |
84 | builder.push_field(field.as_builder_field()); |
85 | builder.push_setter_fn(field.as_setter()); |
86 | build_fn.push_initializer(field.as_initializer()); |
87 | } |
88 | |
89 | builder.push_build_fn(build_fn); |
90 | |
91 | quote!(#builder) |
92 | } |
93 | |