use core::array::TryFromSliceError;
#[cfg(feature = "std")]
use std::io::Error as IoError;

#[cfg(feature = "std")]
use thiserror::Error;

#[cfg_attr(feature = "std", derive(Error, Debug))]
pub enum RapiraError {
    #[cfg_attr(feature = "std", error("iter next error"))]
    IterNext,
    #[cfg_attr(feature = "std", error("string from utf8 error"))]
    StringType,
    #[cfg_attr(feature = "std", error("datetime error"))]
    Datetime,
    #[cfg_attr(feature = "std", error("map insert error: args next error"))]
    MapInsert,
    #[cfg_attr(feature = "std", error("enum variant error"))]
    EnumVariant,
    #[cfg_attr(feature = "std", error("non zero to zero"))]
    FloatIsNaN,
    #[cfg_attr(feature = "std", error("float is NaN"))]
    Decimal,
    #[cfg_attr(feature = "std", error("decimal scale error"))]
    NonZero,
    #[cfg_attr(feature = "std", error("slice len error"))]
    SliceLen,
    #[cfg_attr(feature = "std", error("from arr not implemented"))]
    FromArrNotImplemented,
    #[cfg_attr(feature = "std", error("max size error"))]
    MaxSize,
    #[cfg_attr(feature = "std", error("max capacity error"))]
    MaxCapacity,
    #[cfg_attr(feature = "postcard", error(transparent))]
    #[cfg(feature = "postcard")]
    Postcard(#[from] postcard::Error),
    #[cfg_attr(feature = "std", error(transparent))]
    TryFromSlice(#[cfg_attr(feature = "std", from)] TryFromSliceError),
    #[cfg(feature = "std")]
    #[cfg_attr(feature = "std", error("io error: {0}"))]
    Io(#[from] IoError),
    #[cfg_attr(
        feature = "std",
        error("schema mismatch: peer field type differs from local")
    )]
    SchemaMismatch,
    #[cfg_attr(feature = "std", error("unknown enum variant in peer schema"))]
    UnknownVariant,
    #[cfg_attr(
        feature = "std",
        error("unsupported schema node (Custom) cannot be skipped")
    )]
    UnsupportedSchema,
    #[cfg_attr(feature = "std", error("other error: {0}"))]
    Other(&'static str),
}

pub type Result<T, E = RapiraError> = core::result::Result<T, E>;
