Skip to content

Commit 125f72b

Browse files
committed
feat: add AsRef<str> for Version
Allows getting a static string slice of the version, rather than a `String`. Conflicts: src/version.rs
1 parent 65f5c41 commit 125f72b

File tree

1 file changed

+130
-114
lines changed

1 file changed

+130
-114
lines changed

src/version.rs

Lines changed: 130 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,130 @@
1-
use serde::{de::Error, de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
2-
/// The version of the HTTP protocol in use.
3-
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4-
#[non_exhaustive]
5-
pub enum Version {
6-
/// HTTP/0.9
7-
Http0_9,
8-
9-
/// HTTP/1.0
10-
Http1_0,
11-
12-
/// HTTP/1.1
13-
Http1_1,
14-
15-
/// HTTP/2.0
16-
Http2_0,
17-
18-
/// HTTP/3.0
19-
Http3_0,
20-
}
21-
22-
impl Serialize for Version {
23-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24-
where
25-
S: Serializer,
26-
{
27-
serializer.serialize_str(&self.to_string())
28-
}
29-
}
30-
31-
struct VersionVisitor;
32-
33-
impl<'de> Visitor<'de> for VersionVisitor {
34-
type Value = Version;
35-
36-
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
37-
write!(formatter, "a HTTP version as &str")
38-
}
39-
40-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
41-
where
42-
E: Error,
43-
{
44-
match v {
45-
"HTTP/0.9" => Ok(Version::Http0_9),
46-
"HTTP/1.0" => Ok(Version::Http1_0),
47-
"HTTP/1.1" => Ok(Version::Http1_1),
48-
"HTTP/2" => Ok(Version::Http2_0),
49-
"HTTP/3" => Ok(Version::Http3_0),
50-
_ => Err(Error::invalid_value(serde::de::Unexpected::Str(v), &self)),
51-
}
52-
}
53-
54-
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
55-
where
56-
E: Error,
57-
{
58-
self.visit_str(&v)
59-
}
60-
}
61-
62-
impl<'de> Deserialize<'de> for Version {
63-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64-
where
65-
D: Deserializer<'de>,
66-
{
67-
deserializer.deserialize_str(VersionVisitor)
68-
}
69-
}
70-
71-
impl std::fmt::Display for Version {
72-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73-
f.write_str(match self {
74-
Version::Http0_9 => "HTTP/0.9",
75-
Version::Http1_0 => "HTTP/1.0",
76-
Version::Http1_1 => "HTTP/1.1",
77-
Version::Http2_0 => "HTTP/2",
78-
Version::Http3_0 => "HTTP/3",
79-
})
80-
}
81-
}
82-
83-
#[cfg(test)]
84-
mod test {
85-
use super::*;
86-
#[test]
87-
fn to_string() {
88-
let output = format!(
89-
"{} {} {} {} {}",
90-
Version::Http0_9,
91-
Version::Http1_0,
92-
Version::Http1_1,
93-
Version::Http2_0,
94-
Version::Http3_0
95-
);
96-
assert_eq!("HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3", output);
97-
}
98-
99-
#[test]
100-
fn ord() {
101-
use Version::*;
102-
assert!(Http3_0 > Http2_0);
103-
assert!(Http2_0 > Http1_1);
104-
assert!(Http1_1 > Http1_0);
105-
assert!(Http1_0 > Http0_9);
106-
}
107-
108-
#[test]
109-
fn serde() -> Result<(), serde_json::Error> {
110-
assert_eq!("\"HTTP/3\"", serde_json::to_string(&Version::Http3_0)?);
111-
assert_eq!(Version::Http1_1, serde_json::from_str("\"HTTP/1.1\"")?);
112-
Ok(())
113-
}
114-
}
1+
use serde::{de::Error, de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
2+
/// The version of the HTTP protocol in use.
3+
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
4+
#[non_exhaustive]
5+
pub enum Version {
6+
/// HTTP/0.9
7+
Http0_9,
8+
9+
/// HTTP/1.0
10+
Http1_0,
11+
12+
/// HTTP/1.1
13+
Http1_1,
14+
15+
/// HTTP/2.0
16+
Http2_0,
17+
18+
/// HTTP/3.0
19+
Http3_0,
20+
}
21+
22+
impl Serialize for Version {
23+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24+
where
25+
S: Serializer,
26+
{
27+
serializer.serialize_str(&self.to_string())
28+
}
29+
}
30+
31+
struct VersionVisitor;
32+
33+
impl<'de> Visitor<'de> for VersionVisitor {
34+
type Value = Version;
35+
36+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
37+
write!(formatter, "a HTTP version as &str")
38+
}
39+
40+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
41+
where
42+
E: Error,
43+
{
44+
match v {
45+
"HTTP/0.9" => Ok(Version::Http0_9),
46+
"HTTP/1.0" => Ok(Version::Http1_0),
47+
"HTTP/1.1" => Ok(Version::Http1_1),
48+
"HTTP/2" => Ok(Version::Http2_0),
49+
"HTTP/3" => Ok(Version::Http3_0),
50+
_ => Err(Error::invalid_value(serde::de::Unexpected::Str(v), &self)),
51+
}
52+
}
53+
54+
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
55+
where
56+
E: Error,
57+
{
58+
self.visit_str(&v)
59+
}
60+
}
61+
62+
impl<'de> Deserialize<'de> for Version {
63+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64+
where
65+
D: Deserializer<'de>,
66+
{
67+
deserializer.deserialize_str(VersionVisitor)
68+
}
69+
}
70+
71+
impl AsRef<str> for Version {
72+
fn as_ref(&self) -> &'static str {
73+
match self {
74+
Version::Http0_9 => "HTTP/0.9",
75+
Version::Http1_0 => "HTTP/1.0",
76+
Version::Http1_1 => "HTTP/1.1",
77+
Version::Http2_0 => "HTTP/2",
78+
Version::Http3_0 => "HTTP/3",
79+
}
80+
}
81+
}
82+
83+
impl std::fmt::Display for Version {
84+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85+
f.write_str(self.as_ref())
86+
}
87+
}
88+
89+
#[cfg(test)]
90+
mod test {
91+
use super::*;
92+
93+
#[test]
94+
fn as_ref() {
95+
assert_eq!(Version::Http0_9.as_ref(), "HTTP/0.9");
96+
assert_eq!(Version::Http1_0.as_ref(), "HTTP/1.0");
97+
assert_eq!(Version::Http1_1.as_ref(), "HTTP/1.1");
98+
assert_eq!(Version::Http2_0.as_ref(), "HTTP/2");
99+
assert_eq!(Version::Http3_0.as_ref(), "HTTP/3");
100+
}
101+
102+
#[test]
103+
fn to_string() {
104+
let output = format!(
105+
"{} {} {} {} {}",
106+
Version::Http0_9,
107+
Version::Http1_0,
108+
Version::Http1_1,
109+
Version::Http2_0,
110+
Version::Http3_0
111+
);
112+
assert_eq!("HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/3", output);
113+
}
114+
115+
#[test]
116+
fn ord() {
117+
use Version::*;
118+
assert!(Http3_0 > Http2_0);
119+
assert!(Http2_0 > Http1_1);
120+
assert!(Http1_1 > Http1_0);
121+
assert!(Http1_0 > Http0_9);
122+
}
123+
124+
#[test]
125+
fn serde() -> Result<(), serde_json::Error> {
126+
assert_eq!("\"HTTP/3\"", serde_json::to_string(&Version::Http3_0)?);
127+
assert_eq!(Version::Http1_1, serde_json::from_str("\"HTTP/1.1\"")?);
128+
Ok(())
129+
}
130+
}

0 commit comments

Comments
 (0)