use core::fmt;
use rama_core::error::BoxError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParseError {
Empty,
InvalidComponent(Component),
ControlCharInUri { at: usize, byte: u8 },
InvalidPercentEncoding { at: usize },
IPv6ZoneNotSupported,
#[cfg(not(feature = "idna"))]
#[cfg_attr(docsrs, doc(cfg(not(feature = "idna"))))]
IdnaNotEnabled,
StrictViolation,
TooLong { len: usize },
NonUtf8 { at: usize },
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Empty => f.write_str("uri is empty"),
Self::InvalidComponent(c) => write!(f, "invalid {c} component"),
Self::ControlCharInUri { at, byte } => {
write!(f, "control character 0x{byte:02X} at byte {at}")
}
Self::InvalidPercentEncoding { at } => {
write!(f, "invalid percent-encoded escape at byte {at}")
}
Self::IPv6ZoneNotSupported => f.write_str(
"IPv6 zone identifiers are not currently supported in uri host literals",
),
#[cfg(not(feature = "idna"))]
Self::IdnaNotEnabled => {
f.write_str("non-ASCII host requires the `idna` feature to be enabled")
}
Self::StrictViolation => f.write_str("input does not satisfy RFC 3986 strict syntax"),
Self::TooLong { len } => write!(f, "uri is {len} bytes long, exceeds the maximum"),
Self::NonUtf8 { at } => {
write!(f, "invalid UTF-8 byte sequence starting at byte {at}")
}
}
}
}
impl core::error::Error for ParseError {}
#[derive(Debug)]
pub enum UriError {
InvalidComponent {
component: Component,
cause: ParseError,
},
ComponentConversion {
component: Component,
cause: BoxError,
},
AsteriskOperation,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Component {
Scheme,
Authority,
UserInfo,
Host,
Port,
Path,
Query,
Fragment,
}
impl fmt::Display for Component {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Scheme => "scheme",
Self::Authority => "authority",
Self::UserInfo => "userinfo",
Self::Host => "host",
Self::Port => "port",
Self::Path => "path",
Self::Query => "query",
Self::Fragment => "fragment",
})
}
}
impl fmt::Display for UriError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidComponent { component, cause } => {
write!(f, "invalid {component} component: {cause}")
}
Self::ComponentConversion { component, cause } => {
write!(f, "{component} component conversion failed: {cause}")
}
Self::AsteriskOperation => {
f.write_str("operation is not valid on the asterisk-form uri")
}
}
}
}
impl core::error::Error for UriError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Self::InvalidComponent { cause, .. } => Some(cause),
Self::ComponentConversion { cause, .. } => Some(cause.as_ref()),
Self::AsteriskOperation => None,
}
}
}