safe_uri 0.1.0-beta.4

Simple and safe URI types.
Documentation
use crate::*;
use std::{error::Error, fmt, net::AddrParseError, num::ParseIntError};

#[derive(Debug, Clone)]
pub struct ParseUriError(pub(super) ParseUriErr);

#[derive(Debug, Clone)]
pub(super) enum ParseUriErr {
    Scheme(InvalidScheme),
    MissingScheme,
    UserInfo(InvalidUserInfo),

    // We may want to combine these host variants into a separate enum, inclduing the ipv6 variant
    HostName(InvalidHostName),
    Ipv6(AddrParseError),

    Port(ParseIntError),
    NonDigitPortByte(u8),
    Path(InvalidPath),
    Query(InvalidQuery),
    Fragment(InvalidFragment),
}

impl Error for ParseUriError {}

impl fmt::Display for ParseUriError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str("failed to parse URI: ")?;
        match &self.0 {
            ParseUriErr::Scheme(x) => fmt::Display::fmt(x, f),
            ParseUriErr::MissingScheme => write!(f, "URI has no scheme"),
            ParseUriErr::UserInfo(x) => fmt::Display::fmt(x, f),
            ParseUriErr::HostName(x) => fmt::Display::fmt(x, f),
            ParseUriErr::Ipv6(x) => fmt::Display::fmt(x, f),
            ParseUriErr::Port(x) => fmt::Display::fmt(x, f),
            ParseUriErr::NonDigitPortByte(x) => write!(
                f,
                "invalid port: byte {} ('{}') is not an ASCII digit",
                x,
                char::from(*x),
            ),
            ParseUriErr::Path(x) => fmt::Display::fmt(x, f),
            ParseUriErr::Query(x) => fmt::Display::fmt(x, f),
            ParseUriErr::Fragment(x) => fmt::Display::fmt(x, f),
        }
    }
}