use alloc::boxed::Box;
use core::fmt;
use std::io;
use crate::error;
#[non_exhaustive]
#[derive(Debug)]
pub enum Format {
#[non_exhaustive]
InsufficientTypeInformation,
InvalidComponent(&'static str),
ComponentRange(Box<error::ComponentRange>),
StdIo(io::Error),
}
impl fmt::Display for Format {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InsufficientTypeInformation => f.write_str(
"The type being formatted does not contain sufficient information to format a \
component.",
),
Self::InvalidComponent(component) => write!(
f,
"The {component} component cannot be formatted into the requested format."
),
Self::ComponentRange(err) => err.fmt(f),
Self::StdIo(err) => err.fmt(f),
}
}
}
impl From<error::ComponentRange> for Format {
fn from(err: error::ComponentRange) -> Self {
Self::ComponentRange(Box::new(err))
}
}
impl From<io::Error> for Format {
fn from(err: io::Error) -> Self {
Self::StdIo(err)
}
}
impl TryFrom<Format> for error::ComponentRange {
type Error = error::DifferentVariant;
fn try_from(err: Format) -> Result<Self, Self::Error> {
match err {
Format::ComponentRange(err) => Ok(*err),
_ => Err(error::DifferentVariant),
}
}
}
impl TryFrom<Format> for io::Error {
type Error = error::DifferentVariant;
fn try_from(err: Format) -> Result<Self, Self::Error> {
match err {
Format::StdIo(err) => Ok(err),
_ => Err(error::DifferentVariant),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Format {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::InsufficientTypeInformation | Self::InvalidComponent(_) => None,
Self::ComponentRange(err) => Some(&**err),
Self::StdIo(err) => Some(err),
}
}
}
impl From<Format> for crate::Error {
fn from(original: Format) -> Self {
Self::Format(original)
}
}
impl TryFrom<crate::Error> for Format {
type Error = error::DifferentVariant;
fn try_from(err: crate::Error) -> Result<Self, Self::Error> {
match err {
crate::Error::Format(err) => Ok(err),
_ => Err(error::DifferentVariant),
}
}
}
#[cfg(feature = "serde")]
impl Format {
#[doc(hidden)] pub fn into_invalid_serde_value<S: serde::Serializer>(self) -> S::Error {
use serde::ser::Error;
S::Error::custom(self)
}
}