1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/// # OneOf — Enum variant projection for Rust
///
/// `OneOf` generates ergonomic methods to access individual enum variants
/// without writing repetitive `match` arms. It provides a **zero-cost abstraction**
/// — the generated code compiles to the same machine code as hand-written match.
///
/// ## Motivation
///
/// Rust enums are powerful, but accessing one variant at a time requires
/// boilerplate:
///
/// ```rust
/// # use oneof::OneOf;
/// #[derive(OneOf)]
/// enum Event {
/// Request { id: u64, path: String },
/// Error(String),
/// Timeout,
/// }
///
/// // Instead of:
/// let event = Event::Timeout;
/// let is_timeout = match &event {
/// Event::Timeout => true,
/// _ => false,
/// };
///
/// // Write:
/// assert!(event.is_timeout());
///
/// // Instead of:
/// fn get_error(e: &Event) -> Option<&String> {
/// match e {
/// Event::Error(msg) => Some(msg),
/// _ => None,
/// }
/// }
///
/// // Write:
/// let e = Event::Error("boom".into());
/// assert_eq!(e.error(), Some(&"boom".into()));
/// ```
///
/// ## Generated methods
///
/// For each variant `Foo`, `#[derive(OneOf)]` generates:
///
/// | Method | Signature | Description |
/// |--------|-----------|-------------|
/// | `foo()` | `(&self) -> Option<&Payload>` | Reference to the variant payload |
/// | `foo_mut()` | `(&mut self) -> Option<&mut Payload>` | Mutable reference |
/// | `into_foo()` | `(self) -> Option<Payload>` | Consume and extract |
/// | `is_foo()` | `(&self) -> bool` | Check variant |
///
/// The payload type depends on the variant shape:
///
/// | Variant | Return type of `foo()` |
/// |---------|----------------------|
/// | `Foo` (unit) | `Option<()>` |
/// | `Foo(T)` (single tuple) | `Option<&T>` |
/// | `Foo(T0, T1)` (multi tuple) | `Option<(&T0, &T1)>` |
/// | `Foo { field: T }` (single named) | `Option<&T>` |
/// | `Foo { f0: T0, f1: T1 }` (multi named) | `Option<(&T0, &T1)>` |
///
/// ## Real-world usage
///
/// Filtering collections becomes concise:
///
/// ```rust
/// # use oneof::OneOf;
/// #[derive(OneOf)]
/// enum Status {
/// Active(u32),
/// Inactive,
/// Error(String),
/// }
///
/// let items = vec![
/// Status::Active(1),
/// Status::Inactive,
/// Status::Active(2),
/// Status::Error("fail".into()),
/// ];
///
/// // Extract all active IDs:
/// let active_ids: Vec<&u32> = items.iter().filter_map(|x| x.active()).collect();
/// assert_eq!(active_ids, vec![&1, &2]);
///
/// // Find the first error:
/// let first_error: Option<&String> = items.iter().filter_map(|x| x.error()).next();
/// assert_eq!(first_error, Some(&"fail".into()));
/// ```
///
/// ## Generics and lifetimes
///
/// ```rust
/// # use oneof::OneOf;
/// #[derive(OneOf)]
/// enum RefOrOwned<'a, T: Clone> {
/// Ref(&'a T),
/// Owned(T),
/// }
/// ```
///
/// ## `no_std` support
///
/// This crate is `#![no_std]` compatible. The derive macro only depends on
/// `Option` and `match`, both available in `core`.
///
/// ## Comparison with `strum`
///
/// [`strum`](https://crates.io/crates/strum) is great for enum-wide operations
/// (iterating variants, converting to strings, counting). `OneOf` complements
/// it by generating per-variant accessor methods — something `strum` doesn't
/// provide. They can be used together.
pub use OneOf;
/// Marker trait for enums that support variant projection.
///
/// This trait is **not automatically derived** by `#[derive(OneOf)]`.
/// Implement it manually if you need a trait bound:
///
/// ```rust
/// use oneof::{OneOf, OneOfVariant};
///
/// #[derive(OneOf)]
/// enum MyEnum { A, B }
///
/// // Manual implementation (empty trait, one line):
/// impl OneOfVariant for MyEnum {}
///
/// fn accepts_one_of<T: OneOfVariant>() { /* ... */ }
/// accepts_one_of::<MyEnum>();
/// ```