1use crate::syntax::is_token;
5use std::{error::Error, fmt, str::FromStr};
6
7#[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}