#[macro_use] extern crate pretty_assertions; #[macro_use] extern crate derive_builder; mod field_level { use derive_builder::UninitializedFieldError; #[derive(Debug, PartialEq, Default, Builder, Clone)] struct Lorem { required: String, #[builder(default)] explicit_default: String, #[builder(default = "\"foo\".to_string()")] escaped_default: String, #[builder(default = r#"format!("Hello {}!", "World")"#)] raw_default: String, #[builder(default = r#"format!("{}-{}-{}-{}", Clone::clone(self.required .as_ref() .ok_or_else(|| UninitializedFieldError::new("required"))?), match self.explicit_default { Some(ref x) => x, None => "EMPTY" }, self.escaped_default.as_ref().map(|x| x.as_ref()).unwrap_or("EMPTY"), if let Some(ref x) = self.raw_default { x } else { "EMPTY" })"#)] computed_default: String, } #[test] fn error_if_uninitialized() { let error = LoremBuilder::default().build().unwrap_err(); assert_eq!(&error.to_string(), "`required` must be initialized"); } #[test] fn custom_default() { let x = LoremBuilder::default() .required("ipsum".to_string()) .build() .unwrap(); assert_eq!( x, Lorem { required: "ipsum".to_string(), explicit_default: "".to_string(), escaped_default: "foo".to_string(), raw_default: "Hello World!".to_string(), computed_default: "ipsum-EMPTY-EMPTY-EMPTY".to_string(), } ); } #[test] fn builder_test() { let x = LoremBuilder::default() .required("ipsum".to_string()) .explicit_default("lorem".to_string()) .escaped_default("dolor".to_string()) .raw_default("sit".to_string()) .build() .unwrap(); assert_eq!( x, Lorem { required: "ipsum".to_string(), explicit_default: "lorem".to_string(), escaped_default: "dolor".to_string(), raw_default: "sit".to_string(), computed_default: "ipsum-lorem-dolor-sit".to_string(), } ); } } mod struct_level { #[derive(Debug, Clone, PartialEq, Eq, Builder)] #[builder(default = "explicit_default()")] struct Lorem { #[builder(default = "true")] overwritten: bool, not_type_default: Option<&'static str>, } fn explicit_default() -> Lorem { Lorem { overwritten: false, not_type_default: Some("defined on struct-level"), } } #[derive(Debug, Clone, PartialEq, Eq, Builder)] #[builder(default)] struct Ipsum { not_type_default: Option, also_custom: bool, is_type_default: String, } impl Default for Ipsum { fn default() -> Self { Ipsum { not_type_default: Some(20), also_custom: true, is_type_default: Default::default(), } } } #[test] fn explicit_defaults_are_equal() { let lorem = LoremBuilder::default().build().unwrap(); assert_eq!( lorem, Lorem { overwritten: true, ..explicit_default() } ); } #[test] fn implicit_defaults_are_equal() { let ipsum = IpsumBuilder::default().build().unwrap(); assert_eq!(ipsum, Ipsum::default()); } #[test] fn overrides_work() { let ipsum = IpsumBuilder::default() .not_type_default(None) .build() .expect("Struct-level default makes all fields optional"); assert_eq!(ipsum.not_type_default, None); } }