use crate::types::NoOp;
use core::fmt::{self, Debug, Display, Formatter};
pub(crate) mod types {
#[allow(unused)]
use super::*;
pub type Cond<T> = CondOr<T, NoOp>;
#[derive(Clone, Copy)]
pub struct CondOr<T, U = T> {
pub(super) value: Result<T, U>,
}
#[derive(Clone, Copy)]
pub struct CondWith<F> {
pub(super) make_value: F,
}
}
use types::*;
pub fn cond<T>(write: bool, value: T) -> Cond<T> {
cond_option(if write { Some(value) } else { None })
}
pub fn cond_or<T, U>(write: bool, value: T, fallback: U) -> CondOr<T, U> {
cond_result(if write { Ok(value) } else { Err(fallback) })
}
pub fn cond_option<T>(option: Option<T>) -> Cond<T> {
cond_option_or(option, crate::no_op())
}
pub fn cond_option_or<T, U>(option: Option<T>, fallback: U) -> CondOr<T, U> {
cond_result(option.ok_or(fallback))
}
pub fn cond_result<T, U>(result: Result<T, U>) -> CondOr<T, U> {
CondOr { value: result }
}
pub fn cond_with<R, F>(write: bool, f: F) -> CondWith<Option<F>>
where
F: Fn() -> R,
{
CondWith { make_value: if write { Some(f) } else { None } }
}
pub fn cond_with_option<R, F>(f: F) -> CondWith<F>
where
F: Fn() -> Option<R>,
{
CondWith { make_value: f }
}
impl<T: Debug, U: Debug> Debug for CondOr<T, U> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match &self.value {
Ok(value) => value.fmt(f),
Err(value) => value.fmt(f),
}
}
}
impl<T: Display, U: Display> Display for CondOr<T, U> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match &self.value {
Ok(value) => value.fmt(f),
Err(value) => value.fmt(f),
}
}
}
impl<F, R> Debug for CondWith<Option<F>>
where
F: Fn() -> R,
R: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if let Some(make_value) = &self.make_value {
make_value().fmt(f)?;
}
Ok(())
}
}
impl<F, R> Display for CondWith<Option<F>>
where
F: Fn() -> R,
R: Display,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if let Some(make_value) = &self.make_value {
make_value().fmt(f)?;
}
Ok(())
}
}
impl<F, R> Debug for CondWith<F>
where
F: Fn() -> Option<R>,
R: Debug,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if let Some(value) = (self.make_value)() {
value.fmt(f)?;
}
Ok(())
}
}
impl<F, R> Display for CondWith<F>
where
F: Fn() -> Option<R>,
R: Display,
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
if let Some(value) = (self.make_value)() {
value.fmt(f)?;
}
Ok(())
}
}