use alloc::string::String;
#[cfg(feature = "std")]
use std::io;
use thiserror::Error;
use crate::{
error::ProtoError,
rr::RecordType,
serialize::{binary::DecodeError, txt::Token},
};
pub type ParseResult<T> = ::core::result::Result<T, ParseError>;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum ParseError {
#[error("invalid numerical character: {0}")]
CharToInt(char),
#[error("{0}")]
Message(&'static str),
#[error("token is missing: {0}")]
MissingToken(String),
#[error("{0}")]
Msg(String),
#[error("invalid time string: {0}")]
ParseTime(String),
#[error("unrecognized token in stream: {0:?}")]
UnexpectedToken(Token),
#[error("network address parse error: {0}")]
AddrParse(#[from] core::net::AddrParseError),
#[error("data encoding error: {0}")]
DataEncoding(#[cfg_attr(feature = "std", source)] data_encoding::DecodeError),
#[cfg(feature = "std")]
#[error("io error: {0}")]
Io(#[from] io::Error),
#[error("lexer error: {0}")]
Lexer(#[from] LexerError),
#[error("error parsing number: {0}")]
ParseInt(#[from] core::num::ParseIntError),
#[error("proto error: {0}")]
Proto(#[from] ProtoError),
#[error("unknown RecordType: {0}")]
UnknownRecordType(u16),
#[error("unsupported RecordType: {0}")]
UnsupportedRecordType(RecordType),
}
impl Clone for ParseError {
fn clone(&self) -> Self {
use ParseError::*;
match self {
CharToInt(c) => CharToInt(*c),
Message(msg) => Message(msg),
MissingToken(s) => MissingToken(s.clone()),
Msg(msg) => Msg(msg.clone()),
ParseTime(s) => ParseTime(s.clone()),
UnexpectedToken(token) => UnexpectedToken(token.clone()),
AddrParse(e) => AddrParse(e.clone()),
DataEncoding(e) => DataEncoding(*e),
#[cfg(feature = "std")]
Io(e) => Io(io::Error::from(e.kind())),
Lexer(e) => Lexer(e.clone()),
ParseInt(e) => ParseInt(e.clone()),
Proto(e) => Proto(e.clone()),
UnsupportedRecordType(ty) => UnsupportedRecordType(*ty),
UnknownRecordType(ty) => UnknownRecordType(*ty),
}
}
}
impl From<data_encoding::DecodeError> for ParseError {
fn from(e: data_encoding::DecodeError) -> Self {
Self::DataEncoding(e)
}
}
impl From<&'static str> for ParseError {
fn from(msg: &'static str) -> Self {
Self::Message(msg)
}
}
impl From<String> for ParseError {
fn from(msg: String) -> Self {
Self::Msg(msg)
}
}
impl From<DecodeError> for ParseError {
fn from(e: DecodeError) -> Self {
Self::from(ProtoError::from(e))
}
}
impl From<core::convert::Infallible> for ParseError {
fn from(_e: core::convert::Infallible) -> Self {
panic!("infallible")
}
}
#[cfg(feature = "std")]
impl From<ParseError> for io::Error {
fn from(e: ParseError) -> Self {
Self::other(e)
}
}
pub(crate) type LexerResult<T> = Result<T, LexerError>;
#[derive(Eq, PartialEq, Debug, Error, Clone)]
#[non_exhaustive]
pub enum LexerError {
#[error("unexpected end of input")]
EOF,
#[error("illegal character input: {0}")]
IllegalCharacter(char),
#[error("illegal state: {0}")]
IllegalState(&'static str),
#[error("{0}")]
Message(&'static str),
#[error("unclosed list, missing ')'")]
UnclosedList,
#[error("unclosed quoted string")]
UnclosedQuotedString,
#[error("unrecognized character input: {0}")]
UnrecognizedChar(char),
#[error("unrecognized dollar content: {0}")]
UnrecognizedDollar(String),
#[error("unrecognized octet: {0:x}")]
UnrecognizedOctet(u32),
}