//! Marker trait for types that implement the const formatting methods.
//!
//!
use crate PWrapper;
use PhantomData;
////////////////////////////////////////////////////////////////////////////////
/// Marker trait for types that implement the const formatting methods.
///
/// Debug formatting can be derived using the [`ConstDebug`] derive macro.
///
/// # Implementors
///
/// Types that implement this trait are also expected to implement at least one of
/// these inherent methods:
///
/// ```ignore
/// // use const_format::{Error, Format};
///
/// const fn const_debug_fmt(&self, &mut Formatter<'_>) -> Result<(), Error>
///
/// const fn const_display_fmt(&self, &mut Formatter<'_>) -> Result<(), Error>
/// ```
///
/// # Coercions
///
/// The [`Kind`](#associatedtype.Kind) and [`This`](#associatedtype.This) associated types
/// are used in the [`IsAFormatMarker`] marker type
/// to automatically wrap types in [`PWrapper`] if they're from the standard library,
/// otherwise leaving them unwrapped.
///
/// # Examples
///
/// ### Display formatting
///
/// This example demonstrates how you can implement display formatting,
/// without using the [`impl_fmt`] macro.
///
/// ```rust
/// #![feature(const_mut_refs)]
///
/// use const_format::{
/// marker_traits::{FormatMarker, IsNotStdKind},
/// Error, Formatter, StrWriter,
/// formatc, writec,
/// };
///
/// use std::cmp::Ordering;
///
///
/// struct Compared(u32, Ordering, u32);
///
/// // This is what the `impl_fmt` macro implements implicitly for all non-std types
/// impl FormatMarker for Compared {
/// type Kind = IsNotStdKind;
/// type This = Self;
/// }
///
/// impl Compared {
/// pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
/// let op = match self.1 {
/// Ordering::Less => "<",
/// Ordering::Equal => "==",
/// Ordering::Greater => ">",
/// };
/// writec!(f, "{} {} {}", self.0, op, self.2)
/// }
/// }
///
/// const S_0: &str = formatc!("{}", Compared(0, Ordering::Less, 1));
/// const S_1: &str = formatc!("{}", Compared(1, Ordering::Equal, 1));
/// const S_2: &str = formatc!("{}", Compared(2, Ordering::Greater, 1));
///
/// assert_eq!(S_0, "0 < 1");
/// assert_eq!(S_1, "1 == 1");
/// assert_eq!(S_2, "2 > 1");
///
/// ```
///
/// ### Debug formatting
///
/// For examples of using the [`ConstDebug`] derive macro,
/// [look here](crate::ConstDebug#examples).
///
/// These are examples of implementing debug formatting using the `impl_fmt` macro for:
///
/// - [Tupled structs and tuple variants.](../fmt/struct.DebugTuple.html#example)
///
/// - [Braced structs and braced variants.](../fmt/struct.DebugStruct.html#example)
///
///
/// [`IsAFormatMarker`]: ./struct.IsAFormatMarker.html
/// [`ConstDebug`]: crate::ConstDebug
/// [`impl_fmt`]: ../macro.impl_fmt.html
///
/// Marker type for arrays and slices,
/// used as the [`Kind`] associated type in [`FormatMarker`].
///
/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind
///
;
/// Marker type for the remaining standard library types,,
/// used as the [`Kind`] associated type in [`FormatMarker`].
///
/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind
///
;
/// Marker type for non-standard library types,
/// used as the [`Kind`] associated type in [`FormatMarker`].
///
/// [`Kind`]: ./trait.FormatMarker.html#associatedtype.Kind
///
;
///////////////////////////////////////////////////////////////////////////////
/// Hack used to automatically wrap standard library types inside [`PWrapper`],
/// while leaving user defined types unwrapped.
///
/// # Type parameters
///
/// `K` is `<R as FormatMarker>::Kind`
/// The kind of type that `T` is,
/// [a slice](./struct.IsArrayKind.html),
/// [other std types](./struct.IsStdKind.html),
/// [non-std types](./struct.IsNotStdKind.html).
///
/// `T` is `<R as FormatMarker>::This`:
/// The `R` type after removing all layers of references.
///
/// `R`: a type that implements [`FormatMarker`].
///
/// # Coerce Method
///
/// The `coerce` method is what does the conversion from a `&T` depending on
/// the `K` type parameter:
///
/// - [`IsArrayKind`]: the reference is coerced to a slice, and wrapped in a [`PWrapper`].
///
/// - [`IsStdKind`]: the referenced value is copied, and wrapped in a [`PWrapper`].
///
/// - [`IsNotStdKind`]: the reference is simply returned as a `&T`.
///
>,
,
,
)>,
);
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
std_kind_impls!