use std::num::NonZero;
mod seal {
pub trait Sealed {}
pub trait SealedPossiblyOption<T> {}
}
pub trait StringOrStr: seal::Sealed {
fn to_string(self) -> String;
}
impl seal::Sealed for String {}
impl<'a> seal::Sealed for &'a str {}
impl StringOrStr for String {
fn to_string(self) -> String {
self
}
}
impl<'a> StringOrStr for &'a str {
fn to_string(self) -> String {
self.to_owned()
}
}
pub trait OptionStringOrStr: seal::Sealed {
fn to_option_string(self) -> Option<String>;
}
impl<S> OptionStringOrStr for S
where
S: StringOrStr,
{
fn to_option_string(self) -> Option<String> {
Some(self.to_string())
}
}
impl<S> seal::Sealed for Option<S> where S: StringOrStr {}
impl<S> OptionStringOrStr for Option<S>
where
S: StringOrStr,
{
fn to_option_string(self) -> Option<String> {
self.map(StringOrStr::to_string)
}
}
pub trait PossiblyBoundsChecked<N>: seal::Sealed {
fn to_unchecked(self) -> N;
}
pub trait OptionPossiblyBoundsChecked<N>: seal::Sealed {
fn to_option_unchecked(self) -> Option<N>;
}
macro_rules! impl_possibly_bounds_checked {
{ $($num:ty)+ } => {
$(
impl seal::Sealed for $num {}
impl seal::Sealed for NonZero<$num> {}
impl seal::Sealed for Option<$num> {}
impl seal::Sealed for Option<NonZero<$num>> {}
impl PossiblyBoundsChecked<$num> for $num {
fn to_unchecked(self) -> $num {
self
}
}
impl PossiblyBoundsChecked<$num> for NonZero<$num> {
fn to_unchecked(self) -> $num {
self.get()
}
}
impl OptionPossiblyBoundsChecked<$num> for $num {
fn to_option_unchecked(self) -> Option<$num> {
Some(self)
}
}
impl OptionPossiblyBoundsChecked<$num> for Option<$num> {
fn to_option_unchecked(self) -> Option<$num> {
self
}
}
impl OptionPossiblyBoundsChecked<$num> for NonZero<$num> {
fn to_option_unchecked(self) -> Option<$num> {
Some(self.get())
}
}
impl OptionPossiblyBoundsChecked<$num> for Option<NonZero<$num>> {
fn to_option_unchecked(self) -> Option<$num> {
self.map(|v| v.get())
}
}
)+
}
}
impl_possibly_bounds_checked! { u8 u16 u32 u64 u128 }
pub trait PossiblyOption<T>: seal::SealedPossiblyOption<T> {
fn to_option(self) -> Option<T>;
}
impl<T> seal::SealedPossiblyOption<T> for T {}
impl<T> seal::SealedPossiblyOption<T> for Option<T> {}
impl<T> PossiblyOption<T> for T {
fn to_option(self) -> Option<T> {
Some(self)
}
}
impl<T> PossiblyOption<T> for Option<T> {
fn to_option(self) -> Option<T> {
self
}
}