#[cfg(feature = "non_basic")]
mod non_basic_fmt;
#[cfg(feature = "non_basic")]
mod fmt_compressed;
pub mod char_formatting;
#[cfg(feature = "non_basic")]
pub use self::{fmt_compressed::PackedFmtArg, non_basic_fmt::*};
use crate::wrapper::StdWrapper;
use core::marker::PhantomData;
use typewit::{Identity, TypeEq};
#[cfg_attr(feature = "non_basic", doc = "```rust")]
#[cfg_attr(not(feature = "non_basic"), doc = "```ignore")]
pub trait PanicFmt {
type This: ?Sized;
type Kind;
const PV_COUNT: usize;
const PROOF: IsPanicFmt<Self, Self::This, Self::Kind> = IsPanicFmt::NEW;
}
impl<'a, T: PanicFmt + ?Sized> PanicFmt for &'a T {
type This = T::This;
type Kind = T::Kind;
const PV_COUNT: usize = T::PV_COUNT;
}
pub struct IsStdType;
pub struct IsCustomType;
pub struct IsPanicFmt<S: ?Sized, T: ?Sized, K> {
self_: PhantomData<fn() -> S>,
this: PhantomData<fn() -> T>,
kind: PhantomData<fn() -> K>,
_priv: (),
}
impl<T: PanicFmt + ?Sized> IsPanicFmt<T, T::This, T::Kind> {
pub const NEW: Self = Self {
self_: PhantomData,
this: PhantomData,
kind: PhantomData,
_priv: (),
};
}
impl<S: ?Sized, T: ?Sized, K> IsPanicFmt<S, T, K> {
pub const fn infer(self, _: &S) -> Self {
self
}
pub const fn coerce<'a>(self, x: &'a T) -> CoerceReturnOutput<&'a T, K>
where
<K as Identity>::Type: CoerceReturn<&'a T>,
{
match <K as CoerceReturn<&'a T>>::__COERCE_TO_WITNESS {
__CoerceToWitness::IsStdType(te) => te.to_left(StdWrapper(x)),
__CoerceToWitness::IsCustomType(te) => te.to_left(x),
}
}
}
impl<S: ?Sized, T: ?Sized, K> Copy for IsPanicFmt<S, T, K> {}
impl<S: ?Sized, T: ?Sized, K> Clone for IsPanicFmt<S, T, K> {
fn clone(&self) -> Self {
*self
}
}
pub type CoerceReturnOutput<T, K> = <K as CoerceReturn<T>>::CoerceTo;
pub trait CoerceReturn<T>: Sized {
type CoerceTo;
#[doc(hidden)]
const __COERCE_TO_WITNESS: __CoerceToWitness<T, Self>;
}
impl<T> CoerceReturn<T> for IsStdType {
type CoerceTo = StdWrapper<T>;
#[doc(hidden)]
const __COERCE_TO_WITNESS: __CoerceToWitness<T, Self> =
__CoerceToWitness::IsStdType(TypeEq::NEW);
}
impl<T> CoerceReturn<T> for IsCustomType {
type CoerceTo = T;
#[doc(hidden)]
const __COERCE_TO_WITNESS: __CoerceToWitness<T, Self> =
__CoerceToWitness::IsCustomType(TypeEq::NEW);
}
#[doc(hidden)]
pub enum __CoerceToWitness<T, K: CoerceReturn<T>> {
#[non_exhaustive]
IsStdType(TypeEq<<K as CoerceReturn<T>>::CoerceTo, StdWrapper<T>>),
#[non_exhaustive]
IsCustomType(TypeEq<<K as CoerceReturn<T>>::CoerceTo, T>),
}
#[cfg_attr(feature = "non_basic", doc = "```rust")]
#[cfg_attr(not(feature = "non_basic"), doc = "```ignore")]
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct FmtArg {
pub indentation: u8,
pub is_alternate: bool,
pub fmt_kind: FmtKind,
pub number_fmt: NumberFmt,
}
impl FmtArg {
pub const DISPLAY: Self = Self {
indentation: 0,
fmt_kind: FmtKind::Display,
is_alternate: false,
number_fmt: NumberFmt::Decimal,
};
pub const ALT_DISPLAY: Self = Self::DISPLAY.set_alternate(true);
pub const DEBUG: Self = Self::DISPLAY.set_debug();
pub const ALT_DEBUG: Self = Self::DEBUG.set_alternate(true);
pub const BIN: Self = Self::DISPLAY.set_bin();
pub const ALT_BIN: Self = Self::BIN.set_alternate(true);
pub const HEX: Self = Self::DISPLAY.set_hex();
pub const ALT_HEX: Self = Self::HEX.set_alternate(true);
pub const fn set_alternate(mut self, is_alternate: bool) -> Self {
self.is_alternate = is_alternate;
self
}
pub const fn set_display(mut self) -> Self {
self.fmt_kind = FmtKind::Display;
self
}
pub const fn set_debug(mut self) -> Self {
self.fmt_kind = FmtKind::Debug;
self
}
pub const fn set_hex(mut self) -> Self {
self.fmt_kind = FmtKind::Debug;
self.number_fmt = NumberFmt::Hexadecimal;
self
}
pub const fn set_bin(mut self) -> Self {
self.fmt_kind = FmtKind::Debug;
self.number_fmt = NumberFmt::Binary;
self
}
}
#[cfg(feature = "non_basic")]
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "non_basic")))]
impl FmtArg {
pub const fn indent(mut self) -> Self {
self.indentation += INDENTATION_STEP;
self
}
pub const fn unindent(mut self) -> Self {
self.indentation = self.indentation.saturating_sub(INDENTATION_STEP);
self
}
}
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum FmtKind {
Debug = 0,
Display = 1,
}
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum NumberFmt {
Decimal = 0,
Binary = 1,
Hexadecimal = 2,
}