Skip to content

Commit c3225eb

Browse files
authored
feat: add support for #[builder(into)] attribute (#9)
* feat: add support for #[builder(into)] attribute * update readme * update dependencies version * update typesafe_builder_derive version * update dependencies version and readme
1 parent 2472fbe commit c3225eb

File tree

11 files changed

+319
-185
lines changed

11 files changed

+319
-185
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "typesafe_builder"
3-
version = "1.4.0"
3+
version = "1.5.0"
44
edition = "2024"
55
authors = ["tomoikey"]
66
readme = "README.md"
@@ -10,4 +10,4 @@ license = "MIT"
1010
description = "A procedural macro to generate type-safe builder patterns for Rust structs"
1111

1212
[dependencies]
13-
typesafe_builder_derive = "1.4.0"
13+
typesafe_builder_derive = "1.5.0"

README.md

Lines changed: 68 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div align="center">
22

3-
# 🦀 TypeSafe Builder 🦀
3+
# TypeSafe Builder
44

55
<div>
66
<img src="https://img.shields.io/crates/v/typesafe_builder.svg" alt="crates.io"/>
@@ -18,7 +18,7 @@
1818
</a>
1919
</div>
2020

21-
<h3>🚀 Compile-Time Type Safety • 🧬 Zero Runtime Cost • Blazing Fast Builds</h3>
21+
<h3>Compile-Time Type Safety • Zero Runtime Cost • Blazing Fast Builds</h3>
2222

2323
**The Ultimate Builder Pattern Implementation Powered by Rust's Type System**
2424

@@ -29,7 +29,7 @@
2929
---
3030
</div>
3131

32-
## Why TypeSafe Builder?
32+
## Why TypeSafe Builder?
3333

3434
Traditional builder patterns can't detect missing required fields until runtime.
3535
**TypeSafe Builder** leverages Rust's powerful type system to verify all constraints **at compile time**.
@@ -47,22 +47,23 @@ let user = UserBuilder::new()
4747
.build(); // Always guaranteed to succeed
4848
```
4949

50-
## 🎯 Key Features
50+
## Key Features
5151

52-
### 🔒 **Type-Level Constraint System**
52+
### Type-Level Constraint System
5353
- **Required Fields** - Completely prevent missing required field configuration
5454
- **Optional Fields** - Freely configurable fields
5555
- **Default Values** - Fields with intelligent default values using any Rust expression
5656
- **Conditional Requirements** - Express dynamic dependencies at the type level
5757
- **Complex Logic** - Support for AND/OR/NOT operators in complex conditional expressions
58+
- **Into Conversion** - Ergonomic setters with automatic type conversion via `Into<T>`
5859

59-
### **Performance Characteristics**
60+
### Performance Characteristics
6061
- **Zero Runtime Cost** - All validation completed at compile time
6162

62-
### 🛡️ **Safety Guarantees**
63+
### Safety Guarantees
6364
- **No Panic** - Complete elimination of runtime panics
6465

65-
## 📦 Quick Start
66+
## Quick Start
6667

6768
```toml
6869
[dependencies]
@@ -89,9 +90,9 @@ let user = UserBuilder::new()
8990
.build(); // email will be "[email protected]"
9091
```
9192

92-
## 🚀 Advanced Features
93+
## Advanced Features
9394

94-
### 1️⃣ **Conditional Required Fields**
95+
### 1. Conditional Required Fields
9596

9697
```rust
9798
use typesafe_builder::*;
@@ -119,7 +120,7 @@ let account2 = AccountBuilder::new()
119120
// .build();
120121
```
121122

122-
### 2️⃣ **Conditional Optional Fields**
123+
### 2. Conditional Optional Fields
123124

124125
```rust
125126
use typesafe_builder::*;
@@ -143,7 +144,7 @@ let config2 = ConfigBuilder::new()
143144
.build();
144145
```
145146

146-
### 3️⃣ **Complex Conditional Logic**
147+
### 3. Complex Conditional Logic
147148

148149
```rust
149150
use typesafe_builder::*;
@@ -198,7 +199,7 @@ let client3 = ApiClientBuilder::new()
198199
.build();
199200
```
200201

201-
### 4️⃣ **Default Values**
202+
### 4. Default Values
202203

203204
```rust
204205
use typesafe_builder::*;
@@ -252,14 +253,14 @@ struct AppConfig {
252253
}
253254
```
254255

255-
**Key features of default values:**
256-
- **Flexible expressions**: Use any valid Rust expression as default value
257-
- **No type restrictions**: Works with primitives, collections, function calls, etc.
258-
- **Environment variables**: Access environment variables at build time
259-
- **Function calls**: Call any function or method as default value
260-
- **Standalone attribute**: Cannot be combined with `required`, `optional`, etc.
256+
Key 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.
261262

262-
### 5️⃣ **Negation Operator Support**
263+
### 5. Negation Operator Support
263264

264265
```rust
265266
use typesafe_builder::*;
@@ -281,7 +282,43 @@ let db = DatabaseBuilder::new()
281282
.build();
282283
```
283284

284-
### 6️⃣ **Custom Builder Name**
285+
### 6. Into Conversion Support
286+
287+
The `#[builder(into)]` attribute allows setter methods to accept any type that implements `Into<T>` for the field type `T`, providing more ergonomic APIs:
288+
289+
```rust
290+
use typesafe_builder::*;
291+
292+
#[derive(Builder)]
293+
struct User {
294+
#[builder(required)]
295+
#[builder(into)]
296+
name: String,
297+
298+
#[builder(optional)]
299+
#[builder(into)]
300+
email: Option<String>,
301+
}
302+
303+
// ✅ Accept &str directly (converts to String via Into)
304+
let user1 = UserBuilder::new()
305+
.with_name("Alice") // &str -> String
306+
.with_email("[email protected]") // &str -> String
307+
.build();
308+
309+
// ✅ Still works with String directly
310+
let user2 = UserBuilder::new()
311+
.with_name("Bob".to_string())
312+
.build();
313+
```
314+
315+
Key benefits:
316+
- Ergonomic APIs: Accept `&str` for `String` fields without manual conversion
317+
- Type flexibility: Any `Into<T>` implementation works automatically
318+
- Zero overhead: Conversion happens at the call site
319+
- Backward compatible: Works alongside existing setter patterns
320+
321+
### 7. Custom Builder Name
285322

286323
```rust
287324
use typesafe_builder::*;
@@ -299,7 +336,7 @@ let user = MyCustomBuilder::new()
299336
.build();
300337
```
301338

302-
## 🔧 Error Handling
339+
## Error Handling
303340

304341
### Compile-Time Error Examples
305342

@@ -337,7 +374,7 @@ let config = ConfigBuilder::new()
337374
// method `build` is available on `ConfigBuilder<_TypesafeBuilderFilled, _TypesafeBuilderFilled>`
338375
```
339376

340-
## 🔍 Real-World Use Cases
377+
## Real-World Use Cases
341378

342379
### Web API Configuration
343380

@@ -392,7 +429,7 @@ struct DatabaseConfig {
392429
}
393430
```
394431

395-
## 🤝 Contributing
432+
## Contributing
396433

397434
We welcome contributions to TypeSafe Builder!
398435

@@ -414,7 +451,7 @@ cargo test
414451
cargo test --package typesafe_builder_derive --test ui
415452
```
416453

417-
## 👥 Contributors
454+
## Contributors
418455

419456
Amazing developers who have contributed to this project:
420457

@@ -428,7 +465,7 @@ Amazing developers who have contributed to this project:
428465
<br />
429466
<sub><b>tomoikey</b></sub>
430467
<br />
431-
<sub>🧠 Creator & Maintainer</sub>
468+
<sub>Creator & Maintainer</sub>
432469
</a>
433470
</td>
434471
<td align="center">
@@ -437,7 +474,7 @@ Amazing developers who have contributed to this project:
437474
<br />
438475
<sub><b>ramsyana</b></sub>
439476
<br />
440-
<sub>🔧 Contributor</sub>
477+
<sub>Contributor</sub>
441478
</a>
442479
</td>
443480
<td align="center">
@@ -446,7 +483,7 @@ Amazing developers who have contributed to this project:
446483
<br />
447484
<sub><b>Your Name Here</b></sub>
448485
<br />
449-
<sub>🚀 Next Contributor</sub>
486+
<sub>Next Contributor</sub>
450487
</a>
451488
</td>
452489
</tr>
@@ -458,13 +495,13 @@ Amazing developers who have contributed to this project:
458495

459496
</div>
460497

461-
## 📄 License
498+
## License
462499

463500
MIT License - see the [LICENSE](LICENSE) file for details.
464501

465-
## 🌟 Give us a star!
502+
## Give us a star!
466503

467-
If you find this project useful, please consider giving it a !
504+
If you find this project useful, please consider giving it a star!
468505

469506
---
470507

typesafe_builder_derive/Cargo.lock

Lines changed: 27 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)