#![cfg_attr(not(test), no_std)]
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#[cfg(test)]
mod tests;
use core::fmt::{
Binary, Debug, Display, Formatter, LowerExp, LowerHex, Octal, Pointer, Result, UpperExp,
UpperHex,
};
#[derive(Eq, PartialEq)]
pub struct MaybeFormat<'t, T>(&'t Option<T>);
pub struct MaybeFormatOr<'t, T, U>(&'t Option<T>, U);
pub struct MaybeFormatOrElse<'t, T, F>(&'t Option<T>, F);
impl<'t, T> Copy for MaybeFormat<'t, T> {}
impl<'t, T> Clone for MaybeFormat<'t, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'t, T, U: Copy> Copy for MaybeFormatOr<'t, T, U> {}
impl<'t, T, U: Clone> Clone for MaybeFormatOr<'t, T, U> {
fn clone(&self) -> Self {
Self(self.0, self.1.clone())
}
}
impl<'t, T, F: Copy> Copy for MaybeFormatOrElse<'t, T, F> {}
impl<'t, T, F: Clone> Clone for MaybeFormatOrElse<'t, T, F> {
fn clone(&self) -> Self {
Self(self.0, self.1.clone())
}
}
#[allow(clippy::needless_lifetimes)] pub trait FmtOr<T> {
fn fmt_or_empty<'t>(&'t self) -> MaybeFormat<'t, T>;
fn fmt_or<'t, U>(&'t self, u: U) -> MaybeFormatOr<'t, T, U>
where
U: Display;
fn fmt_or_else<'t, U, F>(&'t self, f: F) -> MaybeFormatOrElse<'t, T, F>
where
U: Display,
F: Fn() -> U;
}
impl<T> FmtOr<T> for Option<T> {
#[inline]
fn fmt_or_empty(&self) -> MaybeFormat<T> {
MaybeFormat(self)
}
#[inline]
fn fmt_or<U>(&self, u: U) -> MaybeFormatOr<T, U>
where
U: Display,
{
MaybeFormatOr(self, u)
}
#[inline]
fn fmt_or_else<U, F>(&self, f: F) -> MaybeFormatOrElse<T, F>
where
U: Display,
F: Fn() -> U,
{
MaybeFormatOrElse(self, f)
}
}
macro_rules! impl_fmt_traits {
($($Trait:ident),*$(,)?) => {$(
impl<'t, T> $Trait for MaybeFormat<'t, T>
where
T: $Trait,
{
#[inline]
fn fmt(&self, out: &mut Formatter<'_>) -> Result {
$Trait::fmt(&self.0.fmt_or(""), out)
}
}
impl<'t, T, U> $Trait for MaybeFormatOr<'t, T, U>
where
T: $Trait,
U: Display,
{
#[inline]
fn fmt(&self, out: &mut Formatter<'_>) -> Result {
$Trait::fmt(&self.0.fmt_or_else(||&self.1), out)
}
}
impl<'t, T, F, U> $Trait for MaybeFormatOrElse<'t, T, F>
where
T: $Trait,
F: Fn() -> U,
U: Display,
{
#[inline]
fn fmt(&self, out: &mut Formatter<'_>) -> Result {
if let Some(t) = self.0 {
<T as $Trait>::fmt(t, out)
} else {
Display::fmt(&self.1(), out)
}
}
}
)*}
}
impl_fmt_traits!(Binary, Debug, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex);