partial-date 0.1.1

Deterministic partial date extraction from natural language text, with sensible defaults and extensive configurability.
Documentation
# partial-date Examples

This directory contains 22+ comprehensive examples demonstrating the `partial-date` library with various configurations and use cases.

## Running the Examples

### Run all examples at once:
```bash
cargo run --example all_examples
```

### Run individual examples:
```bash
# Each example is also available as a standalone file
cargo run --example example_01_basic_dmy
cargo run --example example_02_basic_mdy
cargo run --example example_03_basic_ymd
# ... etc
```

## Example Overview

### Basic Date Formats (1-3)
- **Example 1**: DMY (Day-Month-Year) format - `25/12/2024`
- **Example 2**: MDY (Month-Day-Year) format - `12/25/2024`
- **Example 3**: YMD (Year-Month-Day) format - `2024/12/25`

### Partial Dates (4-6)
- **Example 4**: Day + Month only - `15/06`
- **Example 5**: Month + Year only - `June 2025`
- **Example 6**: Day only - `the 15th`

### Natural Language Month Names (7-9)
- **Example 7**: Full month name - `25 December 2024`
- **Example 8**: Abbreviated month - `15 Dec 2025`
- **Example 9**: Fuzzy/misspelled month - `31 Decmber 2024` (typo correction)

### Year Expansion Modes (10-12)
- **Example 10**: Sliding window (default) - `00-49→2000-2049, 50-99→1950-1999`
- **Example 11**: Always(Century(2000)) - All 2-digit years become `2000-2099`
- **Example 12**: Literal - 2-digit years kept as-is (e.g., `24``24`)

### Ordinal Days (13-15)
- **Example 13**: Ordinal suffix 'st' - `1st December 2024`
- **Example 14**: Various ordinal suffixes - `21st`, `22nd`, `23rd`, `24th`
- **Example 15**: Ordinals in context - `Meeting on the 15th of June`

### Custom Configuration (16-18)
- **Example 16**: Min/max validation - Day must be 10-20
- **Example 17**: Default values - Missing day defaults to 15
- **Example 18**: No-separator concatenated - `25122024` (DDMMYYYY)

### Edge Cases (19-21)
- **Example 19**: Messy input - `25  /  12 - 2024` (extra spacing, mixed separators)
- **Example 20**: Boundary dates - First/last day of year, leap day
- **Example 21**: Fuzzy month matching - Various misspellings detected via Levenshtein distance

### Component Orders (22)
- **Example 22**: All 6 component orders - DMY, MDY, YMD, YDM, MYD, DYM

## Key Features Demonstrated

### Tokenisation
- Separator handling (/, -, ., space, etc.)
- Digit↔alpha boundary detection
- Ordinal suffix recognition
- Month name recognition (full, abbreviated, fuzzy)

### Component Assignment
- Positional assignment based on `ComponentOrder`
- Unambiguous override rules (e.g., day > 31 can't be a month)
- Month-before-day swap in MDY configurations
- `IsExpected` suppression (disabled components)

### Validation
- Min/max bounds checking
- Month range (1-12)
- Day range (1-31)
- Year range (configurable, default 0-3000)

### Defaults
- `Found` - value was extracted
- `Defaulted` - value was not found but a default was configured
- `NotFound` - value was not found and no default available

### Year Expansion
- **Sliding Window**: Smart date interpretation (2024 vs 1999)
- **Always(Century)**: All 2-digit years map to the given century (e.g. `Always(Century(2000))` → 2000-2099)
- **Literal**: 2-digit years preserved as-is

## Configuration Reference

### Basic Config
```rust
let config = Config::default();
```

### With Component Order
```rust
let config = Config {
    component_order: ComponentOrder {
        first: DateComponent::Day,
        second: DateComponent::Month,
        third: DateComponent::Year,
    },
    ..Default::default()
};
```

### With Constraints
```rust
let config = Config {
    day: DayConfig {
        min: 10,
        max: 20,
        expected: IsExpected::Yes,
        default: Some(15),
    },
    ..Default::default()
};
```

### With Year Expansion Mode
```rust
let config = Config {
    year: YearConfig {
        two_digit_expansion: TwoDigitYearExpansion::Always2000s,
        ..Default::default()
    },
    ..Default::default()
};
```

### No-Separator Mode
```rust
let config = Config {
    no_separator: true,
    component_order: ComponentOrder {
        first: DateComponent::Day,
        second: DateComponent::Month,
        third: DateComponent::Year,
    },
    ..Default::default()
};
```

## Input Types

### Basic Input
```rust
let input = Input {
    utterance: "25/12/2024".to_string(),
    config: None,  // Uses library defaults
};
```

### With Custom Config
```rust
let input = Input {
    utterance: "25/12/2024".to_string(),
    config: Some(custom_config),
};
```

## Output Structure

All examples extract a `PartialDate` with three components:

```rust
pub struct PartialDate {
    pub day: Day {
        value: Extracted<u8>,  // Found(15), Defaulted(15), or NotFound
    },
    pub month: Month {
        number: Extracted<u8>,      // 1-12
        name: Extracted<MonthName>, // January, February, etc.
    },
    pub year: Year {
        value: Extracted<i32>,  // Any valid year
    },
}
```

### Extracted Enum
- **`Found(T)`**: Value was successfully extracted
- **`Defaulted(T)`**: Value not found; a configured default was used
- **`NotFound`**: No value extracted and no default available

## Use Cases

These examples cover real-world scenarios:

1. **Global Date Parsing** - Support multiple date conventions (DMY, MDY, YMD)
2. **Natural Language** - Extract dates from user input with month names
3. **Flexible Input** - Handle messy, misspelled, partially-formatted dates
4. **Validation** - Enforce business rules (e.g., only specific date ranges)
5. **Defaults** - Provide sensible fallbacks for missing components
6. **Fuzzy Matching** - Correct minor typos in month names automatically
7. **Legacy Data** - Support concatenated formats (no-separator dates)
8. **Partial Info** - Extract what's available, leave rest as NotFound

## Testing with Examples

Each example includes:
- Clear input description
- Configuration explanation
- Expected output
- Use case context

This makes them excellent for:
- Learning the library API
- Testing custom configurations
- Verifying expected behavior
- Debugging extraction issues