Skip to main content

rama_net/http/
version.rs

1//! HTTP protocol version, owned by rama-net as a protocol primitive.
2//!
3//! Mirrors the shape of the `http` crate's `Version` (opaque, with the
4//! standard `HTTP_09..HTTP_3` constants) so it is a drop-in replacement for
5//! `rama_http_types::Version`, which re-exports this type.
6
7use std::{error::Error, fmt};
8
9use rama_macros::Extension;
10
11/// Represents a version of the HTTP spec.
12#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
13pub struct Version(Http);
14
15#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Extension)]
16#[extension(tags(http))]
17/// Target http version
18///
19/// This can be set manually to enforce a specific version,
20/// otherwise this will be set automatically by things such
21/// tls alpn
22pub struct TargetHttpVersion(pub Version);
23
24#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
25enum Http {
26    Http09,
27    Http10,
28    Http11,
29    H2,
30    H3,
31}
32
33impl Version {
34    /// `HTTP/0.9`
35    pub const HTTP_09: Self = Self(Http::Http09);
36
37    /// `HTTP/1.0`
38    pub const HTTP_10: Self = Self(Http::Http10);
39
40    /// `HTTP/1.1`
41    pub const HTTP_11: Self = Self(Http::Http11);
42
43    /// `HTTP/2.0`
44    pub const HTTP_2: Self = Self(Http::H2);
45
46    /// `HTTP/3.0`
47    pub const HTTP_3: Self = Self(Http::H3);
48
49    fn as_str(self) -> &'static str {
50        match self.0 {
51            Http::Http09 => "HTTP/0.9",
52            Http::Http10 => "HTTP/1.0",
53            Http::Http11 => "HTTP/1.1",
54            Http::H2 => "HTTP/2.0",
55            Http::H3 => "HTTP/3.0",
56        }
57    }
58}
59
60impl Default for Version {
61    #[inline]
62    fn default() -> Self {
63        Self::HTTP_11
64    }
65}
66
67impl core::fmt::Debug for Version {
68    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69        f.write_str(self.as_str())
70    }
71}
72
73/// A possible error value when converting `Version` from bytes
74/// or a related type.
75#[derive(Debug, Default)]
76#[non_exhaustive]
77pub struct InvalidVersion;
78
79impl InvalidVersion {
80    #[inline(always)]
81    pub fn new() -> Self {
82        Self
83    }
84}
85
86impl fmt::Display for InvalidVersion {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        f.write_str("invalid HTTP version")
89    }
90}
91
92impl Error for InvalidVersion {}
93
94// `ApplicationProtocol` (ALPN) <-> `Version` conversions live in `rama-tls`
95// (which depends on both this crate and the TLS enum vocabulary).