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 headers.

/// An ordered list of name/value pairs.  Name comparisons are
/// ASCII-case-insensitive per RFC 9110.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Headers {
    items: Vec<(String, String)>,
}

impl Headers {
    /// An empty header set.
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    /// Return a copy with `name: value` appended.
    #[must_use]
    pub fn with(self, name: impl Into<String>, value: impl Into<String>) -> Self {
        let extended: Vec<(String, String)> = self
            .items
            .into_iter()
            .chain(std::iter::once((name.into(), value.into())))
            .collect();
        Self { items: extended }
    }

    /// Look up the first value for `name` (case-insensitive).
    #[must_use]
    pub fn get(&self, name: &str) -> Option<&str> {
        self.items
            .iter()
            .find(|(k, _)| k.eq_ignore_ascii_case(name))
            .map(|(_, v)| v.as_str())
    }

    /// All header pairs in insertion order.
    pub fn iter(&self) -> std::slice::Iter<'_, (String, String)> {
        self.items.iter()
    }

    /// Number of headers.
    #[must_use]
    pub fn len(&self) -> usize {
        self.items.len()
    }

    /// Whether the set is empty.
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.items.is_empty()
    }
}

impl<'a> IntoIterator for &'a Headers {
    type Item = &'a (String, String);
    type IntoIter = std::slice::Iter<'a, (String, String)>;
    fn into_iter(self) -> Self::IntoIter {
        self.items.iter()
    }
}