#[derive(Copy, Clone)]
pub enum FeOption<T> {
Null,
Unknown,
Known(T),
}
use FeOption::{Known, Null, Unknown};
impl<T> FeOption<T> {
#[inline]
pub const fn is_null(&self) -> bool {
match *self {
Null => true,
_ => false,
}
}
#[inline]
pub const fn is_unknown(&self) -> bool {
match *self {
Unknown => true,
_ => false,
}
}
#[inline]
pub const fn is_known(&self) -> bool {
match *self {
Known(_) => true,
_ => false,
}
}
pub fn unwrap(self) -> T {
match self {
Known(val) => val,
Null => unwrap_failed_null(),
Unknown => unwrap_failed_unknown(),
}
}
}
#[cold]
#[track_caller]
fn unwrap_failed_null() -> ! {
panic!("called `FeOption::unwrap()` on a `Null` value")
}
#[cold]
#[track_caller]
fn unwrap_failed_unknown() -> ! {
panic!("called `FeOption::unwrap()` on an `Unknown` value")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_null_returns_true_only_for_null() {
let n: FeOption<u32> = Null;
let u: FeOption<u32> = Unknown;
let k: FeOption<u32> = Known(7);
assert!(n.is_null());
assert!(!u.is_null());
assert!(!k.is_null());
}
#[test]
fn is_unknown_returns_true_only_for_unknown() {
let n: FeOption<u32> = Null;
let u: FeOption<u32> = Unknown;
let k: FeOption<u32> = Known(7);
assert!(!n.is_unknown());
assert!(u.is_unknown());
assert!(!k.is_unknown());
}
#[test]
fn is_known_returns_true_only_for_known() {
let n: FeOption<u32> = Null;
let u: FeOption<u32> = Unknown;
let k: FeOption<u32> = Known(7);
assert!(!n.is_known());
assert!(!u.is_known());
assert!(k.is_known());
}
#[test]
fn unwrap_known_returns_value() {
let k: FeOption<&str> = Known("air");
assert_eq!(k.unwrap(), "air");
}
#[test]
#[should_panic(expected = "called `FeOption::unwrap()` on a `Null` value")]
fn unwrap_null_panics() {
let n: FeOption<u32> = Null;
let _ = n.unwrap();
}
#[test]
#[should_panic(expected = "called `FeOption::unwrap()` on an `Unknown` value")]
fn unwrap_unknown_panics() {
let u: FeOption<u32> = Unknown;
let _ = u.unwrap();
}
#[test]
fn copy_and_clone_are_supported() {
let k: FeOption<u32> = Known(42);
let n: FeOption<u32> = Null;
let u: FeOption<u32> = Unknown;
let _k_copy = k;
let _n_copy = n;
let _u_copy = u;
let k_clone = k.clone();
let n_clone = n.clone();
let u_clone = u.clone();
assert!(k_clone.is_known());
assert!(n_clone.is_null());
assert!(u_clone.is_unknown());
}
}