1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//! Derive a builder for a struct //! //! This crate implements the _non-consuming_ [builder pattern] as an extension of the //! [custom_derive] macro. //! When applied to a struct, it will derive **setter-methods** for all struct fields. //! //! **Please note**: //! //! * There are slightly different ways to implement the builder pattern in rust. //! The preferred way to do it, is the so called _non-consuming_ variant. //! That means: all generated setter-methods take and return `&mut self`. //! * To complete the builder pattern you only have to implement at least one method //! which actually builds something based on the struct. //! These custom build methods of yours should also take `&mut self` to take advantage of the //! non-consuming pattern. //! * **Don't worry at all** if you have to `clone` or `copy` data in your build methods, //! because luckily the Compiler is smart enough to optimize them away in release builds //! for your every-day use cases. Thats quite a safe bet - we checked this for you. ;-) //! Switching to consuming signatures (=`self`) would not give you any performance //! gain, but only restrict your API for every-day use cases //! //! [builder pattern]: https://aturon.github.io/ownership/builders.html //! [custom_derive]: https://crates.io/crates/custom_derive //! //! # Examples //! //! This crate is best used in combination with [custom_derive]. //! //! ```rust //! #[macro_use] extern crate custom_derive; //! #[macro_use] extern crate derive_builder; //! //! custom_derive!{ //! #[derive(Debug, PartialEq, Default, Clone, Builder)] //! struct Lorem { //! ipsum: String, //! dolor: i32, //! } //! } //! //! fn main() { //! let x = Lorem::default().ipsum("sit").dolor(42).clone(); //! assert_eq!(x, Lorem { ipsum: "sit".into(), dolor: 42 }); //! } //! ``` //! //! In `main()`: The final call of `clone()` represents the act of **building a new struct** //! when our builder is ready. For the sake of brevity we chose clone and pretend we get //! something brand new. As already mentioned, the compiler will optimize this away in release //! mode. //! //! ## Generic structs //! //! ```rust //! #[macro_use] extern crate custom_derive; //! #[macro_use] extern crate derive_builder; //! //! custom_derive!{ //! #[derive(Debug, PartialEq, Default, Clone, Builder)] //! struct GenLorem<T> { //! ipsum: String, //! dolor: T, //! } //! } //! //! fn main() { //! let x = GenLorem::default().ipsum("sit").dolor(42).clone(); //! assert_eq!(x, GenLorem { ipsum: "sit".into(), dolor: 42 }); //! } //! ``` //! //! ## Doc-Comments and Attributes //! //! `#[derive(Builder)]` copies doc-comments and attributes `#[...]` from your fields //! to the according setter-method, if it is one of the following: //! //! * `/// ...` //! * `#[doc = ...]` //! * `#[cfg(...)]` //! * `#[allow(...)]` //! //! ```rust //! #[macro_use] extern crate custom_derive; //! #[macro_use] extern crate derive_builder; //! //! custom_derive!{ //! #[derive(Builder)] //! struct Lorem { //! /// `ipsum` may be any `String` (be creative). //! ipsum: String, //! #[doc = r"`dolor` is the estimated amount of work."] //! dolor: i32, //! // `#[derive(Builder)]` understands conditional compilation via cfg-attributes, //! // i.e. => "no field = no setter". //! #[cfg(target_os = "macos")] //! #[allow(non_snake_case)] //! Im_a_Mac: bool, //! } //! } //! # fn main() {} //! ``` //! //! ## Gotchas //! //! - Tuple structs and unit structs are not supported as they have no field //! names. //! - When defining a generic struct, you cannot use `VALUE` as a generic //! parameter as this is what all setters are using. mod parse_struct; mod derive_builder;