@@ -52,7 +52,7 @@ let user = UserBuilder::new()
5252### Type-Level Constraint System
5353- ** Required Fields** - Completely prevent missing required field configuration
5454- ** Optional Fields** - Freely configurable fields
55- - ** Default Values** - Fields with intelligent default values using any Rust expression
55+ - ** Default Values** - Fields with intelligent default values using ` Default::default() ` or custom expressions
5656- ** Conditional Requirements** - Express dynamic dependencies at the type level
5757- ** Complex Logic** - Support for AND/OR/NOT operators in complex conditional expressions
5858- ** Into Conversion** - Ergonomic setters with automatic type conversion via ` Into<T> `
@@ -81,13 +81,15 @@ struct User {
8181 age : Option <u32 >,
8282 #[builder(default
= " String::from(\ "[email protected] \ " )" )]
8383 email : String ,
84+ #[builder(default)]
85+ active : bool ,
8486}
8587
8688// Type-safe builder pattern
8789let user = UserBuilder :: new ()
8890 . with_name (" Alice" . to_string ())
8991 . with_age (30 )
90- . build ();
// email will be "[email protected] " 92+ . build ();
// email will be "[email protected] ", active will be false 9193```
9294
9395## Advanced Features
@@ -108,7 +110,7 @@ struct Account {
108110// ✅ Compiles successfully
109111let account1 = AccountBuilder :: new (). build ();
110112
111- // ✅ Compiles successfully
113+ // ✅ Compiles successfully
112114let account2 = AccountBuilder :: new ()
113115 . with_email (
" [email protected] " . to_string ())
114116 . with_email_verified (true )
@@ -153,23 +155,23 @@ use typesafe_builder::*;
153155struct ApiClient {
154156 #[builder(optional)]
155157 use_auth : Option <bool >,
156- #[builder(optional)]
158+ #[builder(optional)]
157159 use_https : Option <bool >,
158160 #[builder(optional)]
159161 api_key : Option <String >,
160-
162+
161163 // Secret is required if using auth OR HTTPS
162164 #[builder(required_if = " use_auth || use_https" )]
163165 secret : Option <String >,
164-
166+
165167 // Certificate is required only when using both auth AND HTTPS
166168 #[builder(required_if = " use_auth && use_https" )]
167169 certificate : Option <String >,
168-
170+
169171 // Warning is required when using neither auth NOR HTTPS
170172 #[builder(required_if = " !use_auth && !use_https" )]
171173 insecure_warning : Option <String >,
172-
174+
173175 // Complex condition: Token required when (auth OR HTTPS) AND (no API key)
174176 #[builder(required_if = " (use_auth || use_https) && !api_key" )]
175177 fallback_token : Option <String >,
@@ -201,26 +203,72 @@ let client3 = ApiClientBuilder::new()
201203
202204### 4. Default Values
203205
206+ TypeSafe Builder supports two ways to specify default values:
207+
208+ #### Simple Default Values (using ` Default::default() ` )
209+
210+ ``` rust
211+ use typesafe_builder :: * ;
212+
213+ #[derive(Builder )]
214+ struct Config {
215+ // Uses String::default() (empty string)
216+ #[builder(default)]
217+ name : String ,
218+
219+ // Uses i32::default() (0)
220+ #[builder(default)]
221+ port : i32 ,
222+
223+ // Uses bool::default() (false)
224+ #[builder(default)]
225+ enabled : bool ,
226+
227+ // Uses Vec::default() (empty vector)
228+ #[builder(default)]
229+ items : Vec <String >,
230+
231+ // Uses HashMap::default() (empty map)
232+ #[builder(default)]
233+ metadata : std :: collections :: HashMap <String , String >,
234+
235+ // Works with custom types that implement Default
236+ #[builder(default)]
237+ custom_field : MyCustomType ,
238+
239+ #[builder(required)]
240+ service_name : String ,
241+ }
242+
243+ // ✅ Use default values
244+ let config = ConfigBuilder :: new ()
245+ . with_service_name (" my-service" . to_string ())
246+ . build ();
247+ // name: "", port: 0, enabled: false, items: [], metadata: {}, custom_field: MyCustomType::default()
248+ ```
249+
250+ #### Custom Default Expressions
251+
204252``` rust
205253use typesafe_builder :: * ;
206254
207255#[derive(Builder )]
208256struct ServerConfig {
209257 #[builder(default = " String::from(\ " localhost\ " )" )]
210258 host : String ,
211-
259+
212260 #[builder(default = " 8080" )]
213261 port : u16 ,
214-
262+
215263 #[builder(default = " vec![\ " GET\ " .to_string(), \ " POST\ " .to_string()]" )]
216264 allowed_methods : Vec <String >,
217-
265+
218266 #[builder(default = " std::collections::HashMap::new()" )]
219267 headers : std :: collections :: HashMap <String , String >,
220-
268+
221269 #[builder(required)]
222270 service_name : String ,
223-
271+
224272 #[builder(optional)]
225273 ssl_cert : Option <String >,
226274}
@@ -244,21 +292,51 @@ let config2 = ServerConfigBuilder::new()
244292struct AppConfig {
245293 #[builder(default = " std::env::var(\ " APP_NAME\ " ).unwrap_or_else(|_| \ " default-app\ " .to_string())" )]
246294 app_name : String ,
247-
295+
248296 #[builder(default = " chrono::Utc::now()" )]
249297 created_at : chrono :: DateTime <chrono :: Utc >,
250-
298+
251299 #[builder(default = " uuid::Uuid::new_v4()" )]
252300 instance_id : uuid :: Uuid ,
253301}
254302```
255303
304+ #### Mixed Default Types
305+
306+ ``` rust
307+ use typesafe_builder :: * ;
308+
309+ #[derive(Builder )]
310+ struct MixedConfig {
311+ // Simple default (uses Default::default())
312+ #[builder(default)]
313+ name : String ,
314+
315+ // Custom expression default
316+ #[builder(default = " 42" )]
317+ port : i32 ,
318+
319+ // Simple default for collections
320+ #[builder(default)]
321+ tags : Vec <String >,
322+
323+ // Custom expression for complex initialization
324+ #[builder(default = " std::collections::HashMap::from([(\ " key\ " .to_string(), \ " value\ " .to_string())])" )]
325+ metadata : std :: collections :: HashMap <String , String >,
326+ }
327+
328+ let config = MixedConfigBuilder :: new (). build ();
329+ // name: "", port: 42, tags: [], metadata: {"key": "value"}
330+ ```
331+
256332Key features of default values:
257- - Flexible expressions: Use any valid Rust expression as default value
258- - No type restrictions: Works with primitives, collections, function calls, etc.
259- - Environment variables: Access environment variables at build time
260- - Function calls: Call any function or method as default value
261- - Standalone attribute: Cannot be combined with ` required ` , ` optional ` , etc.
333+ - ** Simple defaults** : Use ` #[builder(default)] ` for types implementing ` Default `
334+ - ** Custom expressions** : Use ` #[builder(default = "expression")] ` for any valid Rust expression
335+ - ** No type restrictions** : Works with primitives, collections, function calls, etc.
336+ - ** Environment variables** : Access environment variables at build time (custom expressions)
337+ - ** Function calls** : Call any function or method as default value (custom expressions)
338+ - ** Standalone attribute** : Cannot be combined with ` required ` , ` optional ` , etc.
339+ - ** Zero runtime cost** : All defaults are computed at build time
262340
263341### 5. Negation Operator Support
264342
@@ -269,7 +347,7 @@ use typesafe_builder::*;
269347struct Database {
270348 #[builder(optional)]
271349 use_ssl : Option <bool >,
272-
350+
273351 // Warning message required when NOT using SSL
274352 #[builder(required_if = " !use_ssl" )]
275353 warning_message : Option <String >,
@@ -294,7 +372,7 @@ struct User {
294372 #[builder(required)]
295373 #[builder(into)]
296374 name : String ,
297-
375+
298376 #[builder(optional)]
299377 #[builder(into)]
300378 email : Option <String >,
@@ -349,7 +427,7 @@ struct User {
349427
350428// ❌ Compile error
351429let user = UserBuilder :: new (). build ();
352- // ^^^^^
430+ // ^^^^^
353431// error: no method named `build` found for struct `UserBuilder<_TypesafeBuilderEmpty>`
354432// method `build` is available on `UserBuilder<_TypesafeBuilderFilled>`
355433```
@@ -369,7 +447,7 @@ struct Config {
369447let config = ConfigBuilder :: new ()
370448 . with_feature (true )
371449 . build ();
372- // ^^^^^
450+ // ^^^^^
373451// error: no method named `build` found for struct `ConfigBuilder<_TypesafeBuilderFilled, _TypesafeBuilderEmpty>`
374452// method `build` is available on `ConfigBuilder<_TypesafeBuilderFilled, _TypesafeBuilderFilled>`
375453```
@@ -383,19 +461,19 @@ let config = ConfigBuilder::new()
383461struct ApiConfig {
384462 #[builder(required)]
385463 base_url : String ,
386-
464+
387465 #[builder(optional)]
388466 use_auth : Option <bool >,
389-
467+
390468 #[builder(required_if = " use_auth" )]
391469 api_key : Option <String >,
392-
470+
393471 #[builder(required_if = " use_auth" )]
394472 secret : Option <String >,
395-
473+
396474 #[builder(default = " 30" )]
397475 timeout_seconds : u64 ,
398-
476+
399477 #[builder(default = " String::from(\ " application/json\ " )" )]
400478 content_type : String ,
401479}
@@ -408,22 +486,22 @@ struct ApiConfig {
408486struct DatabaseConfig {
409487 #[builder(required)]
410488 host : String ,
411-
489+
412490 #[builder(required)]
413491 database : String ,
414-
492+
415493 #[builder(default = " 5432" )]
416494 port : u16 ,
417-
495+
418496 #[builder(default = " 10" )]
419497 max_connections : u32 ,
420-
498+
421499 #[builder(optional)]
422500 use_ssl : Option <bool >,
423-
501+
424502 #[builder(required_if = " use_ssl" )]
425503 ssl_cert_path : Option <String >,
426-
504+
427505 #[builder(optional_if = " !use_ssl" )]
428506 allow_insecure : Option <bool >,
429507}
0 commit comments