use crate::{Class, Tag};
use alloc::str;
use alloc::string;
use alloc::string::String;
use displaydoc::Display;
use nom::error::{ErrorKind, FromExternalError, ParseError};
use nom::IResult;
#[cfg(feature = "std")]
use std::io;
#[cfg(feature = "std")]
use thiserror::Error;
#[cfg(feature = "std")]
impl std::error::Error for DerConstraint {}
#[derive(Clone, Copy, Debug, Display, PartialEq)]
pub enum DerConstraint {
IndefiniteLength,
Constructed,
NotConstructed,
MissingTimeZone,
MissingSeconds,
UnusedBitsNotZero,
InvalidBoolean,
IntegerEmpty,
IntegerLeadingZeroes,
IntegerLeadingFF,
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
#[derive(Clone, Debug, Display, PartialEq)]
pub enum Error {
BerTypeError,
BerValueError,
InvalidLength,
InvalidValue { tag: Tag, msg: String },
InvalidTag,
UnknownTag(u32),
UnexpectedTag { expected: Option<Tag>, actual: Tag },
UnexpectedClass {
expected: Option<Class>,
actual: Class,
},
IndefiniteLengthUnexpected,
ConstructExpected,
ConstructUnexpected,
IntegerTooLarge,
IntegerNegative,
BerMaxDepth,
StringInvalidCharset,
InvalidDateTime,
DerConstraintFailed(DerConstraint),
LifetimeError,
Unsupported,
Incomplete(nom::Needed),
NomError(ErrorKind),
}
impl Error {
#[inline]
pub const fn invalid_value(tag: Tag, msg: String) -> Self {
Self::InvalidValue { tag, msg }
}
#[inline]
pub const fn unexpected_class(expected: Option<Class>, actual: Class) -> Self {
Self::UnexpectedClass { expected, actual }
}
#[inline]
pub const fn unexpected_tag(expected: Option<Tag>, actual: Tag) -> Self {
Self::UnexpectedTag { expected, actual }
}
}
impl<'a> ParseError<&'a [u8]> for Error {
fn from_error_kind(_input: &'a [u8], kind: ErrorKind) -> Self {
Error::NomError(kind)
}
fn append(_input: &'a [u8], kind: ErrorKind, _other: Self) -> Self {
Error::NomError(kind)
}
}
impl From<Error> for nom::Err<Error> {
fn from(e: Error) -> Self {
nom::Err::Error(e)
}
}
impl From<str::Utf8Error> for Error {
fn from(_: str::Utf8Error) -> Self {
Error::StringInvalidCharset
}
}
impl From<string::FromUtf8Error> for Error {
fn from(_: string::FromUtf8Error) -> Self {
Error::StringInvalidCharset
}
}
impl From<string::FromUtf16Error> for Error {
fn from(_: string::FromUtf16Error) -> Self {
Error::StringInvalidCharset
}
}
impl From<nom::Err<Error>> for Error {
fn from(e: nom::Err<Error>) -> Self {
match e {
nom::Err::Incomplete(n) => Self::Incomplete(n),
nom::Err::Error(e) | nom::Err::Failure(e) => e,
}
}
}
impl<I, E> FromExternalError<I, E> for Error {
fn from_external_error(_input: I, kind: ErrorKind, _e: E) -> Error {
Error::NomError(kind)
}
}
pub type ParseResult<'a, T> = IResult<&'a [u8], T, Error>;
pub type Result<T> = core::result::Result<T, Error>;
#[cfg(feature = "std")]
#[derive(Debug, Error)]
pub enum SerializeError {
#[error("ASN.1 error: {0:?}")]
ASN1Error(#[from] Error),
#[error("Invalid Class {class:}")]
InvalidClass { class: u8 },
#[error("Invalid Length")]
InvalidLength,
#[error("I/O error: {0:?}")]
IOError(#[from] io::Error),
}
#[cfg(feature = "std")]
pub type SerializeResult<T> = std::result::Result<T, SerializeError>;