# EzInit
Initialize structs easily with powerful derive macros.
## How does it work?
If you derive `EzInit` on your struct, it will generate a `new()` function that initializes the struct fields based on the following rules:
### Field Initialization Modes
1. **Explicit Default Value**: `#[init(default = <expression>)]`
- Uses the provided expression to initialize the field
- Example: `#[init(default = 100)]`, `#[init(default = "hello".to_string())]`
2. **Default Trait**: `#[init(default)]`
- Uses `Default::default()` for types that implement `Default`
- Example: `#[init(default)]` on a field of type `CharacterClass` (if it derives `Default`)
3. **Random Values**: `#[init(random)]` or `#[init(random = "range")]` or `#[init(random = [items])]`
- `#[init(random)]`: Random value using the type's standard random generation
- `#[init(random = "1..10")]`: Random integer in range
- `#[init(random = "0.0..1.0")]`: Random float in range
- `#[init(random = ["A", "B", "C"])]`: Random item from list
4. **Random Enum Variant**: `#[init(enum)]`
- Picks a random variant from an enum that derives `RandomVariant`
- The enum must only have unit variants (no data)
5. **Option Types**: No attribute needed
- Automatically initialized to `None`
6. **Required Fields**: No attribute
- Becomes a required parameter in the `new()` function
### RandomVariant Derive
For enums, derive `RandomVariant` to enable random variant selection:
- Only works on enums with unit variants (no associated data)
- Can be combined with `Default` derive for flexible initialization
- Implements `Distribution<YourEnum>` for `rand::distributions::Standard`
## Installation
Not published yet, so you need to clone the repo and add it as a path dependency:
```toml
[dependencies]
ezinit = { path = "path/to/ezinit" }
```
## Usage Example
```rust
use ezinit::{EzInit, RandomVariant};
// Derive RandomVariant for random enum selection
#[derive(Debug, Clone, Copy, Default, RandomVariant)]
enum RoadCondition {
#[default]
Excellent,
Good,
Fair,
Poor,
Fatal,
}
#[derive(Debug, Clone, Copy, Default)]
enum RoadType {
Highway,
#[default]
Street,
Avenue,
Hill
}
// Derive EzInit to generate the new() function
#[derive(Debug, EzInit)]
struct HighWay {
// Required field: must be passed to new()
pub name: String,
// Explicit default value
#[init(default = 2)]
pub lanes: u32,
// Random item from list
#[init(random = ["Me", "Cat", "Politician"])]
pub built_by: String,
// Use Default::default() - always returns street
#[init(default)]
pub road_type: RoadType,
// Random enum variant
#[init(enum)]
pub condition: RoadCondition,
// Random integer range
#[init(random = "60..120")]
pub max_speed: u32,
// Random float range
#[init(random = "0.0..100.0")]
pub length_km: f64,
// Option: automatically None
pub toll_cost: Option<f32>,
}
fn main() {
// Only 'name' is required!
let highway = HighWay::new("I-95".to_string());
println!("Highway: {}", highway.name);
println!("Type: {:?} (always default), Condition: {:?} (random)",
highway.road_type, highway.condition);
println!("Built by: {}, Lanes: {}", highway.built_by, highway.lanes);
println!("Max Speed: {} km/h, Length: {:.1} km",
highway.max_speed, highway.length_km);
}
```
### Sample Output
Running the above code produces output like this (values marked as random will differ each run):
```
Highway: I-95
Type: Street (always default), Condition: Good (random)
Built by: Cat, Lanes: 2
Max Speed: 87 km/h, Length: 42.7 km
```
Each time you run the program, the random values will change:
```
Highway: I-95
Type: Street (always default), Condition: Fatal (random)
Built by: Politician, Lanes: 2
Max Speed: 103 km/h, Length: 15.3 km
```
## Generated Code
For the above example, `EzInit` generates:
```rust
impl HighWay {
pub fn new(name: String) -> Self {
Self {
name,
lanes: 2,
built_by: {
use ::ezinit::export::rand::seq::SliceRandom;
["Me", "Cat", "Politician"]
.choose(&mut ::ezinit::export::rand::thread_rng())
.unwrap()
.clone()
.into()
},
road_type: Default::default(),
condition: ::ezinit::export::rand::random(),
max_speed: ::ezinit::export::rand::Rng::gen_range(
&mut ::ezinit::export::rand::thread_rng(),
60..120
),
length_km: ::ezinit::export::rand::Rng::gen_range(
&mut ::ezinit::export::rand::thread_rng(),
0.0..100.0
),
toll_cost: None,
}
}
}
```
## License
MIT