oneof 0.2.0

Enum variant projection — access one variant at a time
Documentation
//! Example: Using `OneOf` with `strum` for enum introspection + variant projection.
//!
//! `strum` provides enum-wide utilities (iteration, display, etc.),
//! while `OneOf` provides per-variant accessor methods.
//! They complement each other perfectly.
//!
//! ```bash
//! cargo run --example strum_interop
//! ```

use oneof::OneOf;
use strum::{Display, EnumCount, EnumIter, IntoStaticStr};

/// A flexible event type benefiting from both libraries:
/// - `strum`: iterate all variants, convert to/from strings
/// - `OneOf`: extract specific variant payloads without match boilerplate
#[derive(OneOf, Debug, PartialEq, EnumIter, EnumCount, Display, IntoStaticStr)]
enum Event {
    /// A request event with id and path
    Request { id: u64, path: String },
    /// An error event with a message
    Error(String),
    /// A timeout marker
    Timeout,
}

fn main() {
    let events = vec![
        Event::Error("timeout".into()),
        Event::Request {
            id: 1,
            path: "/".into(),
        },
        Event::Timeout,
        Event::Request {
            id: 2,
            path: "/about".into(),
        },
        Event::Error("eof".into()),
    ];

    // ---- OneOf: per-variant access ----
    let errors: Vec<&String> = events.iter().filter_map(|e| e.error()).collect();
    println!("Errors (OneOf): {errors:?}");

    let requests: Vec<&u64> = events
        .iter()
        .filter_map(|e| {
            let req = e.request()?;
            Some(req.id)
        })
        .collect();
    println!("Request IDs (OneOf): {requests:?}");

    let timeouts: Vec<()> = events.iter().filter_map(|e| e.timeout()).collect();
    println!("Timeouts (OneOf): {timeouts:?}");

    // ---- strum: enum-wide utilities ----
    use strum::IntoEnumIterator;
    let all_variants: Vec<&str> = Event::iter().map(|v| v.into()).collect();
    println!("All variants (strum): {all_variants:?}");
    println!("Variant count (strum): {}", Event::COUNT);

    // ---- Combined: filter via OneOf, introspect via strum ----
    for event in &events {
        if let Some(msg) = event.error() {
            // Convert the variant to a static string via strum
            let name: &'static str = event.into();
            println!("  Found {name}: {msg}");
        }
    }
}