1 #[macro_use] 2 extern crate pretty_assertions; 3 #[macro_use] 4 extern crate derive_builder; 5 6 mod field_level { 7 #[derive(Debug, PartialEq, Default, Builder, Clone)] 8 struct Lorem { 9 required: String, 10 #[builder(default)] 11 explicit_default: String, 12 #[builder(default = "\"foo\".to_string()")] 13 escaped_default: String, 14 #[builder(default = r#"format!("Hello {}!", "World")"#)] 15 raw_default: String, 16 #[builder( 17 default = r#"format!("{}-{}-{}-{}", 18 Clone::clone(self.required 19 .as_ref() 20 .ok_or("required must be initialized")?), 21 match self.explicit_default { Some(ref x) => x, None => "EMPTY" }, 22 self.escaped_default.as_ref().map(|x| x.as_ref()).unwrap_or("EMPTY"), 23 if let Some(ref x) = self.raw_default { x } else { "EMPTY" })"# 24 )] 25 computed_default: String, 26 } 27 28 #[test] 29 #[should_panic(expected = "`required` must be initialized")] panic_if_uninitialized()30 fn panic_if_uninitialized() { 31 LoremBuilder::default().build().unwrap(); 32 } 33 34 #[test] custom_default()35 fn custom_default() { 36 let x = LoremBuilder::default() 37 .required("ipsum".to_string()) 38 .build() 39 .unwrap(); 40 41 assert_eq!( 42 x, 43 Lorem { 44 required: "ipsum".to_string(), 45 explicit_default: "".to_string(), 46 escaped_default: "foo".to_string(), 47 raw_default: "Hello World!".to_string(), 48 computed_default: "ipsum-EMPTY-EMPTY-EMPTY".to_string(), 49 } 50 ); 51 } 52 53 #[test] builder_test()54 fn builder_test() { 55 let x = LoremBuilder::default() 56 .required("ipsum".to_string()) 57 .explicit_default("lorem".to_string()) 58 .escaped_default("dolor".to_string()) 59 .raw_default("sit".to_string()) 60 .build() 61 .unwrap(); 62 63 assert_eq!( 64 x, 65 Lorem { 66 required: "ipsum".to_string(), 67 explicit_default: "lorem".to_string(), 68 escaped_default: "dolor".to_string(), 69 raw_default: "sit".to_string(), 70 computed_default: "ipsum-lorem-dolor-sit".to_string(), 71 } 72 ); 73 } 74 } 75 76 mod struct_level { 77 #[derive(Debug, Clone, PartialEq, Eq, Builder)] 78 #[builder(default = "explicit_default()")] 79 struct Lorem { 80 #[builder(default = "true")] 81 overwritten: bool, 82 not_type_default: Option<&'static str>, 83 } 84 explicit_default() -> Lorem85 fn explicit_default() -> Lorem { 86 Lorem { 87 overwritten: false, 88 not_type_default: Some("defined on struct-level"), 89 } 90 } 91 92 #[derive(Debug, Clone, PartialEq, Eq, Builder)] 93 #[builder(default)] 94 struct Ipsum { 95 not_type_default: Option<u16>, 96 also_custom: bool, 97 is_type_default: String, 98 } 99 100 impl Default for Ipsum { default() -> Self101 fn default() -> Self { 102 Ipsum { 103 not_type_default: Some(20), 104 also_custom: true, 105 is_type_default: Default::default(), 106 } 107 } 108 } 109 110 #[test] explicit_defaults_are_equal()111 fn explicit_defaults_are_equal() { 112 let lorem = LoremBuilder::default().build().unwrap(); 113 114 assert_eq!( 115 lorem, 116 Lorem { 117 overwritten: true, 118 ..explicit_default() 119 } 120 ); 121 } 122 123 #[test] implicit_defaults_are_equal()124 fn implicit_defaults_are_equal() { 125 let ipsum = IpsumBuilder::default().build().unwrap(); 126 127 assert_eq!(ipsum, Ipsum::default()); 128 } 129 130 #[test] overrides_work()131 fn overrides_work() { 132 let ipsum = IpsumBuilder::default() 133 .not_type_default(None) 134 .build() 135 .expect("Struct-level default makes all fields optional"); 136 137 assert_eq!(ipsum.not_type_default, None); 138 } 139 } 140