//! This example shows combining generics with custom errors and validation. //! //! Note the use of the type parameter in the `#[builder(...)]` attribute. #![allow(dead_code)] use derive_builder::{Builder, UninitializedFieldError}; trait Popular { fn is_popular(&self) -> bool; } impl<'a> Popular for &'a str { fn is_popular(&self) -> bool { !self.starts_with('b') } } #[derive(Debug, Builder)] #[builder(build_fn(validate = "check_person", error = "Error"))] struct Person { name: N, age: u16, } #[derive(Debug)] enum Error { UninitializedField(&'static str), UnpopularName(N), } impl From for Error { fn from(error: UninitializedFieldError) -> Self { Self::UninitializedField(error.field_name()) } } fn check_person(builder: &PersonBuilder) -> Result<(), Error> { if let Some(name) = &builder.name { if !name.is_popular() { return Err(Error::UnpopularName(name.clone())); } } Ok(()) } fn main() { dbg!(PersonBuilder::default() .name("bill") .age(71) .build() .unwrap_err()); }