net-cat 0.2.0

Minimal hand-rolled HTTP/1.1 client over std::net::TcpStream. Plain HTTP in v0; v0.2.0 adds an optional `tls` feature that wires rustls + webpki-roots Mozilla CA bundle so `https://` URLs work via the same `fetch` / `exchange` entry points. No external HTTP crate; framing and parsing are local. No `mut` beyond FFI carve-outs (`TcpStream::read_to_end`, rustls `Stream::new(&mut conn, &mut sock)`). Sixth sub-crate of a Servo-replacement webview runtime targeting Tauri.
//! HTTP-client error type.

/// All errors `net-cat` can produce.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
    /// The URL was malformed.
    InvalidUrl {
        /// The offending source.
        source: String,
    },
    /// The URL used a scheme the v0 client cannot handle.  Currently
    /// returned for anything other than `http`.
    UnsupportedScheme {
        /// The scheme that was attempted.
        scheme: String,
    },
    /// A TCP-level I/O failure.
    Io {
        /// Human description of the failure.
        message: String,
    },
    /// The response status line was malformed.
    InvalidStatusLine {
        /// The text that failed to parse.
        text: String,
    },
    /// A header line was malformed.
    InvalidHeader {
        /// The header line text.
        line: String,
    },
    /// The header name contained illegal bytes.
    InvalidHeaderName {
        /// The name string.
        name: String,
    },
    /// TLS handshake / read / write failure (only produced when the
    /// `tls` feature is enabled).
    Tls {
        /// Human description of the failure.
        message: String,
    },
}

impl From<std::io::Error> for Error {
    fn from(value: std::io::Error) -> Self {
        Self::Io {
            message: format!("{value}"),
        }
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::InvalidUrl { source } => write!(f, "invalid url: {source:?}"),
            Self::UnsupportedScheme { scheme } => write!(f, "unsupported scheme: {scheme:?}"),
            Self::Io { message } => write!(f, "i/o error: {message}"),
            Self::InvalidStatusLine { text } => write!(f, "invalid status line: {text:?}"),
            Self::InvalidHeader { line } => write!(f, "invalid header line: {line:?}"),
            Self::InvalidHeaderName { name } => write!(f, "invalid header name: {name:?}"),
            Self::Tls { message } => write!(f, "tls error: {message}"),
        }
    }
}

impl std::error::Error for Error {}