extern crate alloc;
use alloc::string::String;
use core::fmt;
#[derive(Debug, Clone)]
pub struct Asn1Error {
pub kind: Asn1ErrorKind,
pub pos: usize,
}
#[derive(Debug, Clone)]
pub enum Asn1ErrorKind {
UnexpectedEof,
UnknownTag { tag: u8 },
LengthMismatch { expected: usize, got: usize },
InvalidBool,
InvalidReal,
InvalidString { message: String },
SequenceSizeMismatch {
sequence_end: usize,
content_end: usize,
},
Unsupported { message: String },
InvalidTypeTag { message: String },
InvalidDiscriminant { discriminant: Option<i64> },
}
impl fmt::Display for Asn1Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.kind {
Asn1ErrorKind::UnexpectedEof => {
write!(f, "unexpected end of input at position {}", self.pos)
}
Asn1ErrorKind::UnknownTag { tag } => {
write!(f, "unknown tag 0x{:02x} at position {}", tag, self.pos)
}
Asn1ErrorKind::LengthMismatch { expected, got } => {
write!(
f,
"length mismatch at position {}: expected {}, got {}",
self.pos, expected, got
)
}
Asn1ErrorKind::InvalidBool => {
write!(f, "invalid boolean value at position {}", self.pos)
}
Asn1ErrorKind::InvalidReal => write!(f, "invalid real value at position {}", self.pos),
Asn1ErrorKind::InvalidString { message } => {
write!(f, "invalid string at position {}: {}", self.pos, message)
}
Asn1ErrorKind::SequenceSizeMismatch {
sequence_end,
content_end,
} => {
write!(
f,
"sequence size mismatch: sequence ends at {}, content ends at {}",
sequence_end, content_end
)
}
Asn1ErrorKind::Unsupported { message } => {
write!(f, "unsupported: {}", message)
}
Asn1ErrorKind::InvalidTypeTag { message } => {
write!(f, "invalid type tag: {}", message)
}
Asn1ErrorKind::InvalidDiscriminant { discriminant } => {
if let Some(d) = discriminant {
write!(f, "invalid discriminant: {}", d)
} else {
write!(f, "missing discriminant")
}
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Asn1Error {}
impl Asn1Error {
pub const fn new(kind: Asn1ErrorKind, pos: usize) -> Self {
Self { kind, pos }
}
pub const fn unexpected_eof(pos: usize) -> Self {
Self::new(Asn1ErrorKind::UnexpectedEof, pos)
}
pub const fn unknown_tag(tag: u8, pos: usize) -> Self {
Self::new(Asn1ErrorKind::UnknownTag { tag }, pos)
}
pub fn unsupported(message: impl Into<String>, pos: usize) -> Self {
Self::new(
Asn1ErrorKind::Unsupported {
message: message.into(),
},
pos,
)
}
}