rama_net/forwarded/
version.rs

1#[cfg(feature = "http")]
2use rama_http_types::Version;
3
4#[derive(Debug, PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash)]
5/// Version of the forwarded protocol.
6pub struct ForwardedVersion(VersionKind);
7
8#[derive(Debug, PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash)]
9enum VersionKind {
10    Http09,
11    Http10,
12    Http11,
13    H2,
14    H3,
15}
16
17impl ForwardedVersion {
18    /// `HTTP/0.9`
19    pub const HTTP_09: ForwardedVersion = ForwardedVersion(VersionKind::Http09);
20
21    /// `HTTP/1.0`
22    pub const HTTP_10: ForwardedVersion = ForwardedVersion(VersionKind::Http10);
23
24    /// `HTTP/1.1`
25    pub const HTTP_11: ForwardedVersion = ForwardedVersion(VersionKind::Http11);
26
27    /// `HTTP/2.0`
28    pub const HTTP_2: ForwardedVersion = ForwardedVersion(VersionKind::H2);
29
30    /// `HTTP/3.0`
31    pub const HTTP_3: ForwardedVersion = ForwardedVersion(VersionKind::H3);
32}
33
34#[cfg(feature = "http")]
35impl ForwardedVersion {
36    /// Returns this [`ForwardedVersion`] as a [`Version`] if it is defined as http.
37    pub fn as_http(&self) -> Option<Version> {
38        Some(match self.0 {
39            VersionKind::Http09 => Version::HTTP_09,
40            VersionKind::Http10 => Version::HTTP_10,
41            VersionKind::Http11 => Version::HTTP_11,
42            VersionKind::H2 => Version::HTTP_2,
43            VersionKind::H3 => Version::HTTP_3,
44        })
45    }
46}
47
48rama_utils::macros::error::static_str_error! {
49    #[doc = "invalid forwarded version"]
50    pub struct InvalidForwardedVersion;
51}
52
53impl TryFrom<&str> for ForwardedVersion {
54    type Error = InvalidForwardedVersion;
55
56    #[inline]
57    fn try_from(value: &str) -> Result<Self, Self::Error> {
58        value.as_bytes().try_into()
59    }
60}
61
62impl TryFrom<String> for ForwardedVersion {
63    type Error = InvalidForwardedVersion;
64
65    #[inline]
66    fn try_from(value: String) -> Result<Self, Self::Error> {
67        value.as_bytes().try_into()
68    }
69}
70
71impl TryFrom<Vec<u8>> for ForwardedVersion {
72    type Error = InvalidForwardedVersion;
73
74    #[inline]
75    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
76        value.as_slice().try_into()
77    }
78}
79
80impl TryFrom<&[u8]> for ForwardedVersion {
81    type Error = InvalidForwardedVersion;
82
83    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
84        Ok(ForwardedVersion(match bytes {
85            b"0.9" => VersionKind::Http09,
86            b"1" | b"1.0" => VersionKind::Http10,
87            b"1.1" => VersionKind::Http11,
88            b"2" | b"2.0" => VersionKind::H2,
89            b"3" | b"3.0" => VersionKind::H3,
90            _ => return Err(InvalidForwardedVersion),
91        }))
92    }
93}
94
95impl std::fmt::Display for ForwardedVersion {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        match self.0 {
98            VersionKind::Http09 => f.write_str("0.9"),
99            VersionKind::Http10 => f.write_str("1.0"),
100            VersionKind::Http11 => f.write_str("1.1"),
101            VersionKind::H2 => f.write_str("2"),
102            VersionKind::H3 => f.write_str("3"),
103        }
104    }
105}