service-builder 0.3.0

A lightweight, type-safe service construction library for Rust that provides compile-time dependency injection through builder pattern
Documentation
# service-builder Enhancement Plan

## Current State
service-builder works well for dependency injection patterns but has limitations for configuration structs that need default values and optional fields.

## Enhancement Goals
Make service-builder suitable for both dependency injection AND configuration patterns by adding support for defaults and optional fields.

## Planned Features

### 1. Default Value Support
Add `#[builder(default = "expression")]` attribute support:

```rust
#[builder]
struct CacheConfig {
    #[builder(default = "Duration::from_secs(3600)")]
    default_ttl: Option<Duration>,
    
    #[builder(default = "10_000")]
    max_entries: Option<usize>,
    
    #[builder(default)] // Uses Default::default()
    compression: bool,
    
    #[builder(default = "Duration::from_secs(5)")]
    connection_timeout: Duration,
}
```

**Implementation Plan:**
- Extend `field_attributes.rs` to parse `default` attribute
- Modify builder generation to use defaults for unset fields
- Support both literal expressions and `Default::default()`

### 2. Optional Field Handling
Add `#[builder(optional)]` for fields that should default to `None`:

```rust
#[builder]
struct CacheConfig {
    #[builder(optional)] // Defaults to None if not set
    default_ttl: Option<Duration>,
    
    #[builder(optional)]
    max_entries: Option<usize>,
}
```

**Implementation Plan:**
- Add `optional` attribute parsing
- Generate builder code that doesn't require these fields
- Automatically set to `None` if not provided

### 3. Build Methods Variants
Provide multiple build strategies:

```rust
impl CacheConfigBuilder {
    // Current behavior - fails if required fields missing
    pub fn build(self) -> Result<CacheConfig, BuildError> { ... }
    
    // New - uses defaults, never fails for config structs
    pub fn build_with_defaults(self) -> CacheConfig { ... }
    
    // New - validates all fields are set or have defaults
    pub fn build_validated(self) -> Result<CacheConfig, BuildError> { ... }
}
```

### 4. Custom Builder Methods Support
Allow custom convenience methods alongside generated ones:

```rust
// Generated builder gets custom methods via impl block
impl CacheConfigBuilder {
    // Custom convenience methods
    pub fn no_default_ttl(self) -> Self {
        self.default_ttl(None)
    }
    
    pub fn unlimited_entries(self) -> Self {
        self.max_entries(None)
    }
    
    pub fn enable_compression(self, threshold: usize) -> Self {
        self.compression(true).compression_threshold(threshold)
    }
}
```

### 5. Field Validation Support
Add validation attributes:

```rust
#[builder]
struct CacheConfig {
    #[builder(validate = "validate_ttl")]
    default_ttl: Option<Duration>,
    
    #[builder(validate = "|v| v > 0", message = "Max entries must be positive")]
    max_entries: Option<usize>,
}

fn validate_ttl(ttl: &Option<Duration>) -> Result<(), String> {
    // Custom validation logic
}
```

## Implementation Priority

### Phase 1: Core Default Support
1. `#[builder(default)]` using `Default::default()`
2. `#[builder(default = "expression")]` with literal expressions
3. `build_with_defaults()` method

### Phase 2: Optional Fields
1. `#[builder(optional)]` attribute
2. Automatic `Option<T>` handling
3. Better error messages

### Phase 3: Enhanced Builder Methods
1. `build_validated()` method
2. Custom method support documentation
3. Integration examples

### Phase 4: Validation (Future)
1. `#[builder(validate)]` attribute
2. Custom validation functions
3. Validation error aggregation

## Success Criteria

After implementation, this should work seamlessly:

```rust
#[builder]
struct CacheConfig {
    #[builder(optional)]
    default_ttl: Option<Duration>,
    
    #[builder(optional)]
    max_entries: Option<usize>,
    
    #[builder(default = "Duration::from_secs(5)")]
    connection_timeout: Duration,
    
    #[builder(default)]
    compression: bool,
}

// Usage 1: Minimal config
let config = CacheConfig::builder()
    .build_with_defaults(); // Uses all defaults

// Usage 2: Partial config  
let config = CacheConfig::builder()
    .max_entries(Some(1000))
    .build_with_defaults();

// Usage 3: Full validation
let config = CacheConfig::builder()
    .default_ttl(Some(Duration::from_secs(3600)))
    .max_entries(Some(1000))
    .build_validated()?; // Ensures all fields handled
```

## Testing Strategy

1. **Unit Tests**: Each new attribute and feature
2. **Integration Tests**: Real configuration structs
3. **Regression Tests**: Ensure existing DI patterns still work
4. **Documentation Tests**: All examples in docs compile and run

## Migration Path

1. **Backward Compatible**: All existing code continues to work
2. **Opt-in Features**: New attributes are optional
3. **Clear Documentation**: When to use each pattern
4. **Migration Examples**: Show how to convert manual builders