use core::fmt::{self, Display, Formatter};
use core::marker::PhantomData;
#[cfg(feature = "alloc")]
use alloc::collections::TryReserveError;
#[cfg(feature = "alloc")]
use alloc::ffi::NulError;
#[cfg(feature = "std")]
#[rustversion::since(1.89)]
use std::fs::TryLockError;
#[cfg(feature = "std")]
use std::io::{self, IntoInnerError};
#[cfg_attr(feature = "std", doc = "[`InvalidData`]: io::ErrorKind::InvalidData")]
#[cfg_attr(not(feature = "std"), doc = "[`InvalidData`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.InvalidData>")]
#[cfg_attr(feature = "std", doc = "[`InvalidInput`]: io::ErrorKind::InvalidInput")]
#[cfg_attr(not(feature = "std"), doc = "[`InvalidInput`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.InvalidInput>")]
#[cfg_attr(feature = "std", doc = "[`OutOfMemory`]: io::ErrorKind::OutOfMemory")]
#[cfg_attr(not(feature = "std"), doc = "[`OutOfMemory`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.OutOfMemory>")]
#[cfg_attr(feature = "std", doc = "[`UnexpectedEof`]: io::ErrorKind::UnexpectedEof")]
#[cfg_attr(not(feature = "std"), doc = "[`UnexpectedEof`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.UnexpectedEof>")]
#[cfg_attr(feature = "std", doc = "[`WriteZero`]: io::ErrorKind::WriteZero")]
#[cfg_attr(not(feature = "std"), doc = "[`WriteZero`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WriteZero>")]
#[cfg_attr(not(feature = "std"), doc = "[`io::Error`]: <https://doc.rust-lang.org/nightly/std/io/struct.Error.html>")]
#[derive(Debug)]
pub struct Error {
inner: Inner,
_source: PhantomData<&'static mut (dyn core::error::Error + Send + Sync)>,
}
impl Error {
#[cfg_attr(feature = "std", doc = "[`InvalidData`]: io::ErrorKind::InvalidData")]
#[cfg_attr(not(feature = "std"), doc = "[`InvalidData`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.InvalidData>")]
#[must_use]
pub fn invalid_data() -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(io::ErrorKind::InvalidData.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let inner = Inner::InvalidData;
Self { inner, _source: PhantomData }
}
}
#[cfg_attr(feature = "std", doc = "[`InvalidInput`]: io::ErrorKind::InvalidInput")]
#[cfg_attr(not(feature = "std"), doc = "[`InvalidInput`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.InvalidInput>")]
#[must_use]
pub fn invalid_input() -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(io::ErrorKind::InvalidInput.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let inner = Inner::InvalidInput;
Self { inner, _source: PhantomData }
}
}
#[cfg_attr(feature = "std", doc = "[`OutOfMemory`]: io::ErrorKind::OutOfMemory")]
#[cfg_attr(not(feature = "std"), doc = "[`OutOfMemory`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.OutOfMemory>")]
#[must_use]
pub fn out_of_memory() -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(io::ErrorKind::OutOfMemory.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let inner = Inner::OutOfMemory;
Self { inner, _source: PhantomData }
}
}
#[cfg_attr(feature = "std", doc = "[`UnexpectedEof`]: io::ErrorKind::UnexpectedEof")]
#[cfg_attr(not(feature = "std"), doc = "[`UnexpectedEof`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.UnexpectedEof>")]
#[must_use]
pub fn unexpected_eof() -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(io::ErrorKind::UnexpectedEof.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let inner = Inner::UnexpectedEof;
Self { inner, _source: PhantomData }
}
}
#[cfg_attr(feature = "std", doc = "[`WriteZero`]: io::ErrorKind::WriteZero")]
#[cfg_attr(not(feature = "std"), doc = "[`WriteZero`]: <https://doc.rust-lang.org/nightly/std/io/enum.ErrorKind.html#variant.WriteZero>")]
#[must_use]
pub fn write_zero() -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(io::ErrorKind::WriteZero.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let inner = Inner::WriteZero;
Self { inner, _source: PhantomData }
}
}
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
#[cfg(feature = "std")]
{
let Inner::Io(ref e) = self.inner;
Display::fmt(e, f)
}
#[cfg(not(feature = "std"))]
{
let s = match self.inner {
Inner::InvalidData => "invalid data",
Inner::InvalidInput => "invalid input parameter",
Inner::OutOfMemory => "out of memory",
Inner::UnexpectedEof => "unexpected end of file",
Inner::WriteZero => "write zero",
};
f.write_str(s)
}
}
}
impl core::error::Error for Error {
#[inline]
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
#[cfg(feature = "std")]
{
let Inner::Io(ref e) = self.inner;
Some(e)
}
#[cfg(not(feature = "std"))]
{
None
}
}
}
#[cfg(feature = "std")]
impl From<io::Error> for Error {
#[inline]
fn from(value: io::Error) -> Self {
let inner = Inner::Io(value);
Self { inner, _source: PhantomData }
}
}
#[cfg(feature = "std")]
impl From<io::ErrorKind> for Error {
#[inline]
fn from(value: io::ErrorKind) -> Self {
let inner = Inner::Io(value.into());
Self { inner, _source: PhantomData }
}
}
#[cfg(feature = "std")]
impl<W> From<IntoInnerError<W>> for Error {
#[inline]
fn from(value: IntoInnerError<W>) -> Self {
let inner = Inner::Io(value.into());
Self { inner, _source: PhantomData }
}
}
#[cfg(feature = "alloc")]
impl From<NulError> for Error {
#[inline]
fn from(value: NulError) -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(value.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let _ = value;
let inner = Inner::InvalidData;
Self { inner, _source: PhantomData }
}
}
}
#[expect(clippy::incompatible_msrv)]
#[cfg(feature = "std")]
#[rustversion::since(1.89)]
impl From<TryLockError> for Error {
#[inline]
fn from(value: TryLockError) -> Self {
let inner = Inner::Io(value.into());
Self { inner, _source: PhantomData }
}
}
#[cfg(feature = "alloc")]
impl From<TryReserveError> for Error {
#[inline]
fn from(value: TryReserveError) -> Self {
#[cfg(feature = "std")]
{
let inner = Inner::Io(value.into());
Self { inner, _source: PhantomData }
}
#[cfg(not(feature = "std"))]
{
let _ = value;
let inner = Inner::OutOfMemory;
Self { inner, _source: PhantomData }
}
}
}
#[cfg(feature = "std")]
impl From<Error> for io::Error {
#[inline]
fn from(value: Error) -> Self {
let Inner::Io(e) = value.inner;
e
}
}
#[cfg_attr(not(feature = "std"), repr(usize))]
#[derive(Debug)]
enum Inner {
#[cfg(feature = "std")]
Io(io::Error),
#[cfg(not(feature = "std"))]
InvalidData,
#[cfg(not(feature = "std"))]
InvalidInput,
#[cfg(not(feature = "std"))]
OutOfMemory,
#[cfg(not(feature = "std"))]
UnexpectedEof,
#[cfg(not(feature = "std"))]
WriteZero,
}