staged_builder/
lib.rs

1//! A procedural macro which creates a "staged" builder for a type.
2//!
3//! Staged (also known as telescopic) builders are a style of infallible builders; code will not compile if any required
4//! fields are not set. Specifically, the builder advances in order through a sequence of "stage" types, each
5//! corresponding to a required field of the struct. The final stage has setters for all optional fields and the final
6//! `.build()` method.
7//!
8//! See the documentation for [`#[staged_builder]`](staged_builder) for more details.
9//!
10//! # Examples
11//!
12//! ```
13//! use staged_builder::staged_builder;
14//!
15//! #[staged_builder]
16//! struct Person {
17//!     #[builder(into)]
18//!     name: String,
19//!     age: u32,
20//!     #[builder(list(item(type = Person)))]
21//!     parents: Vec<Person>,
22//! }
23//!
24//! # fn main() {
25//! let person = Person::builder()
26//!     .name("John Doe")
27//!     .age(25)
28//!     .build();
29//! # }
30//! ```
31#![cfg_attr(not(doc), no_std)]
32
33// Not part of the public API.
34#[doc(hidden)]
35pub use staged_builder_internals::__StagedBuilderInternalDerive;
36#[doc(inline)]
37pub use staged_builder_internals::staged_builder;
38
39// Not part of the public API.
40#[doc(hidden)]
41pub mod __private {
42    pub use core::convert::{From, Into};
43    pub use core::default::Default;
44    pub use core::iter::{Extend, FromIterator, IntoIterator, Iterator};
45    pub use core::result::Result;
46
47    #[inline]
48    pub fn call_hack<T, R>(f: impl FnOnce(T) -> R, v: T) -> R {
49        f(v)
50    }
51}
52
53/// A trait for types which validate their state before construction finishes.
54///
55/// The generated builder will call this method if the `#[builder(validate)]` attribute is placed at the struct level.
56pub trait Validate {
57    /// The error returned for an invalid value.
58    type Error;
59
60    /// Validates the state of `self`.
61    fn validate(&self) -> Result<(), Self::Error>;
62}
63
64/// An example type using [`#[staged_builder]`](staged_builder).
65#[cfg(doc)]
66#[staged_builder]
67#[builder(crate = crate)]
68pub struct ExamplePerson {
69    #[builder(into)]
70    pub name: String,
71    pub age: u32,
72    #[builder(list(item(type = ExamplePerson)))]
73    pub parents: Vec<ExamplePerson>,
74}