use nom::error::ErrorKind as NomErrorKind;
use thiserror::Error;
use super::FrameType;
use crate::{
error::{Error as TransportError, ErrorKind as TransportErrorKind},
packet::r#type::Type,
varint::VarInt,
};
#[derive(Debug, Clone, Eq, PartialEq, Error)]
pub enum Error {
#[error("A packet containing no frames")]
NoFrames,
#[error("Incomplete frame type: {0}")]
IncompleteType(String),
#[error("Invalid frame type from {0}")]
InvalidType(VarInt),
#[error("Wrong frame type {0:?}")]
WrongType(FrameType, Type),
#[error("Incomplete frame {0:?}: {1}")]
IncompleteFrame(FrameType, String),
#[error("Error occurred when parsing frame {0:?}: {1}")]
ParseError(FrameType, String),
}
impl From<Error> for TransportError {
fn from(e: Error) -> Self {
match e {
Error::NoFrames => Self::new(
TransportErrorKind::ProtocolViolation,
FrameType::Padding,
e.to_string(),
),
Error::IncompleteType(_) => Self::new(
TransportErrorKind::FrameEncoding,
FrameType::Padding,
e.to_string(),
),
Error::InvalidType(_) => Self::new(
TransportErrorKind::FrameEncoding,
FrameType::Padding,
e.to_string(),
),
Error::WrongType(fty, _) => {
Self::new(TransportErrorKind::FrameEncoding, fty, e.to_string())
}
Error::IncompleteFrame(fty, _) => {
Self::new(TransportErrorKind::FrameEncoding, fty, e.to_string())
}
Error::ParseError(fty, _) => {
Self::new(TransportErrorKind::FrameEncoding, fty, e.to_string())
}
}
}
}
impl From<nom::Err<Error>> for Error {
fn from(value: nom::Err<Error>) -> Self {
match value {
nom::Err::Incomplete(_needed) => {
unreachable!("Because the parsing of QUIC packets and frames is not stream-based.")
}
nom::Err::Error(err) | nom::Err::Failure(err) => err,
}
}
}
impl nom::error::ParseError<&[u8]> for Error {
fn from_error_kind(_input: &[u8], _kind: NomErrorKind) -> Self {
debug_assert_eq!(_kind, NomErrorKind::ManyTill);
unreachable!("QUIC frame parser must always consume")
}
fn append(_input: &[u8], _kind: NomErrorKind, source: Self) -> Self {
debug_assert_eq!(_kind, NomErrorKind::ManyTill);
source
}
}