pub(crate) trait Ite {
type Arg1;
type Arg2;
type Result;
fn ite(&self) -> fn(&bool, Self::Arg1, Self::Arg2) -> Self::Result;
}
impl<T> Ite for &&&&(&Option<T>, &Option<T>) {
type Arg1 = Option<T>;
type Arg2 = Option<T>;
type Result = Option<T>;
fn ite(&self) -> fn(&bool, Self::Arg1, Self::Arg2) -> Self::Result {
|b: &bool, true_val: Option<T>, false_val: Option<T>| {
if *b {
true_val
} else {
false_val
}
}
}
}
impl<T> Ite for &&&(&Option<T>, &T) {
type Arg1 = Option<T>;
type Arg2 = T;
type Result = Option<T>;
fn ite(&self) -> fn(&bool, Self::Arg1, Self::Arg2) -> Self::Result {
|b: &bool, true_val: Option<T>, false_val: T| {
if *b {
true_val
} else {
Some(false_val)
}
}
}
}
impl<T> Ite for &&(&T, &Option<T>) {
type Arg1 = T;
type Arg2 = Option<T>;
type Result = Option<T>;
fn ite(&self) -> fn(&bool, Self::Arg1, Self::Arg2) -> Self::Result {
|b: &bool, true_val: T, false_val: Option<T>| {
if *b {
Some(true_val)
} else {
false_val
}
}
}
}
impl<T> Ite for &(&T, &T) {
type Arg1 = T;
type Arg2 = T;
type Result = T;
fn ite(&self) -> fn(&bool, Self::Arg1, Self::Arg2) -> Self::Result {
|b: &bool, true_val: T, false_val: T| {
if *b {
true_val
} else {
false_val
}
}
}
}
macro_rules! ite {
($b:expr, $true_val:expr, $false_val:expr) => {{
use crate::endpoint_lib::ite::Ite;
let b = $b;
let true_val = $true_val;
let false_val = $false_val;
(&&&&(&true_val, &false_val)).ite()(&b, true_val, false_val)
}};
}
pub(crate) use ite;
#[cfg(test)]
mod test {
use super::*;
#[test]
fn base_cases() {
let a = "a";
let some_a = Some("a");
let b = "b";
let some_b = Some("b");
let none: Option<&str> = None;
assert_eq!(ite!(true, some_a, some_b), Some("a"));
assert_eq!(ite!(false, some_a, some_b), Some("b"));
assert_eq!(ite!(false, some_a, none), None);
assert_eq!(ite!(true, some_a, none), Some("a"));
assert_eq!(ite!(true, some_a, b), Some("a"));
assert_eq!(ite!(false, some_a, b), Some("b"));
assert_eq!(ite!(true, none, b), None);
assert_eq!(ite!(false, none, b), Some("b"));
assert_eq!(ite!(true, a, some_b), Some("a"));
assert_eq!(ite!(false, a, some_b), Some("b"));
assert_eq!(ite!(false, a, none), None);
assert_eq!(ite!(true, a, none), Some("a"));
assert_eq!(ite!(true, a, b), "a");
assert_eq!(ite!(false, a, b), "b");
}
}