hyper_old_types/
version.rs

1//! HTTP Versions enum
2//!
3//! Instead of relying on typo-prone Strings, use expected HTTP versions as
4//! the `HttpVersion` enum.
5use std::fmt;
6use std::str::FromStr;
7
8#[cfg(feature = "compat")]
9use http;
10
11use error::Error;
12use self::HttpVersion::{Http09, Http10, Http11, H2, H2c};
13
14/// Represents a version of the HTTP spec.
15#[derive(PartialEq, PartialOrd, Copy, Clone, Eq, Ord, Hash, Debug)]
16pub enum HttpVersion {
17    /// `HTTP/0.9`
18    Http09,
19    /// `HTTP/1.0`
20    Http10,
21    /// `HTTP/1.1`
22    Http11,
23    /// `HTTP/2.0` over TLS
24    H2,
25    /// `HTTP/2.0` over cleartext
26    H2c,
27    #[doc(hidden)]
28    __DontMatchMe,
29}
30
31impl fmt::Display for HttpVersion {
32    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
33        fmt.write_str(match *self {
34            Http09 => "HTTP/0.9",
35            Http10 => "HTTP/1.0",
36            Http11 => "HTTP/1.1",
37            H2 => "h2",
38            H2c => "h2c",
39            HttpVersion::__DontMatchMe => unreachable!(),
40        })
41    }
42}
43
44impl FromStr for HttpVersion {
45    type Err = Error;
46    fn from_str(s: &str) -> Result<HttpVersion, Error> {
47        Ok(match s {
48            "HTTP/0.9" => Http09,
49            "HTTP/1.0" => Http10,
50            "HTTP/1.1" => Http11,
51            "h2" => H2,
52            "h2c" => H2c,
53            _ => return Err(Error::Version),
54        })
55    }
56}
57
58impl Default for HttpVersion {
59    fn default() -> HttpVersion {
60        Http11
61    }
62}
63
64#[cfg(feature = "compat")]
65impl From<http::Version> for HttpVersion {
66    fn from(v: http::Version) -> HttpVersion {
67        match v {
68            http::Version::HTTP_09 =>
69                HttpVersion::Http09,
70            http::Version::HTTP_10 =>
71                HttpVersion::Http10,
72            http::Version::HTTP_11 =>
73                HttpVersion::Http11,
74            http::Version::HTTP_2 =>
75                HttpVersion::H2
76        }
77    }
78}
79
80#[cfg(feature = "compat")]
81impl From<HttpVersion> for http::Version {
82    fn from(v: HttpVersion) -> http::Version {
83        match v {
84            HttpVersion::Http09 =>
85                http::Version::HTTP_09,
86            HttpVersion::Http10 =>
87                http::Version::HTTP_10,
88            HttpVersion::Http11 =>
89                http::Version::HTTP_11,
90            HttpVersion::H2 =>
91                http::Version::HTTP_2,
92            _ => panic!("attempted to convert unexpected http version")
93        }
94    }
95}
96
97#[cfg(test)]
98mod tests {
99    use std::str::FromStr;
100    use error::Error;
101    use super::HttpVersion;
102    use super::HttpVersion::{Http09,Http10,Http11,H2,H2c};
103
104    #[test]
105    fn test_default() {
106        assert_eq!(Http11, HttpVersion::default());
107    }
108
109    #[test]
110    fn test_from_str() {
111        assert_eq!(Http09, HttpVersion::from_str("HTTP/0.9").unwrap());
112        assert_eq!(Http10, HttpVersion::from_str("HTTP/1.0").unwrap());
113        assert_eq!(Http11, HttpVersion::from_str("HTTP/1.1").unwrap());
114        assert_eq!(H2, HttpVersion::from_str("h2").unwrap());
115        assert_eq!(H2c, HttpVersion::from_str("h2c").unwrap());
116    }
117
118    #[test]
119    fn test_from_str_panic() {
120        match HttpVersion::from_str("foo") {
121            Err(Error::Version) => assert!(true),
122            Err(_) => assert!(false),
123            Ok(_) => assert!(false),
124        }
125    }
126        
127}