Skip to main content

base_http/
protocol.rs

1// Released under the MIT License.
2// Copyright, 2026, by Samuel Williams.
3
4use crate::syntax::is_token;
5use std::{error::Error, fmt, str::FromStr};
6
7/// Application protocol intent (e.g. `websocket`), independent of HTTP version.
8/// A driver translates this into Upgrade or extended CONNECT as appropriate.
9#[derive(Clone, Debug, Eq, Hash, PartialEq)]
10pub struct Protocol(String);
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub struct InvalidProtocol;
14
15impl fmt::Display for InvalidProtocol {
16    fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
17        output.write_str("invalid application protocol token")
18    }
19}
20impl Error for InvalidProtocol {}
21
22impl Protocol {
23    pub fn new(value: impl Into<String>) -> Result<Self, InvalidProtocol> {
24        let value = value.into();
25        if !is_token(value.as_bytes()) {
26            return Err(InvalidProtocol);
27        }
28        Ok(Self(value))
29    }
30    pub fn as_str(&self) -> &str {
31        &self.0
32    }
33}
34impl FromStr for Protocol {
35    type Err = InvalidProtocol;
36    fn from_str(value: &str) -> Result<Self, Self::Err> {
37        Self::new(value)
38    }
39}
40impl fmt::Display for Protocol {
41    fn fmt(&self, output: &mut fmt::Formatter<'_>) -> fmt::Result {
42        output.write_str(self.as_str())
43    }
44}