use core::fmt;
#[cfg(feature = "alloc")]
use alloc::collections::TryReserveError;
#[cfg(feature = "alloc")]
use alloc::string::String;
use crate::buffer::{BufferTooSmallError, Error as BufferError};
pub trait ProcessAndWrite: Sized {
type OutputBorrowed: ?Sized;
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
type OutputOwned;
type ProcessError: fmt::Display;
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
fn allocate_and_write(self) -> Result<Self::OutputOwned, Error<Self::ProcessError>>;
fn write_to_byte_slice(
self,
buf: &mut [u8],
) -> Result<&Self::OutputBorrowed, Error<Self::ProcessError>>;
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
fn append_to_std_string(
self,
buf: &mut String,
) -> Result<&Self::OutputBorrowed, Self::ProcessError> {
match self.try_append_to_std_string(buf) {
Ok(v) => Ok(v),
Err(Error::Buffer(e)) => panic!("buffer error: {}", e),
Err(Error::Process(e)) => Err(e),
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
fn try_append_to_std_string(
self,
buf: &mut String,
) -> Result<&Self::OutputBorrowed, Error<Self::ProcessError>>;
}
#[derive(Debug, Clone)]
pub enum Error<T> {
Buffer(BufferError),
Process(T),
}
impl<T> fmt::Display for Error<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Buffer(_) => f.write_str("buffer error"),
Error::Process(_) => f.write_str("data processing failed"),
}
}
}
impl<T> From<BufferTooSmallError> for Error<T> {
#[inline]
fn from(e: BufferTooSmallError) -> Self {
Self::Buffer(e.into())
}
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
impl<T> From<TryReserveError> for Error<T> {
#[inline]
fn from(e: TryReserveError) -> Self {
Self::Buffer(e.into())
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<T> std::error::Error for Error<T>
where
T: std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Error::Buffer(e) => Some(e),
Error::Process(e) => Some(e),
}
}
}