• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 //! HTTP [`Version`].
15 //!
16 //! HTTP's version number consists of two decimal digits separated by a "."
17 //! (period or decimal point). The first digit (major version) indicates the
18 //! messaging syntax, whereas the second digit (minor version) indicates the
19 //! highest minor version within that major version to which the sender is
20 //! conformant (able to understand for future communication).
21 //!
22 //! [`Version`]: https://httpwg.org/specs/rfc9110.html#protocol.version
23 
24 use core::convert::TryFrom;
25 
26 use crate::error::{ErrorKind, HttpError};
27 
28 /// HTTP [`Version`] implementation.
29 ///
30 /// [`Version`]: https://httpwg.org/specs/rfc9110.html#protocol.version
31 ///
32 /// # Examples
33 ///
34 /// ```
35 /// use ylong_http::version::Version;
36 ///
37 /// assert_eq!(Version::HTTP1_1.as_str(), "HTTP/1.1");
38 /// ```
39 #[derive(Clone, Debug, PartialEq, Eq)]
40 pub struct Version(Inner);
41 
42 impl Version {
43     /// HTTP1.1
44     pub const HTTP1_1: Self = Self(Inner::Http11);
45     /// HTTP2
46     pub const HTTP2: Self = Self(Inner::Http2);
47     /// HTTP3
48     pub const HTTP3: Self = Self(Inner::Http3);
49 
50     /// Converts a `Version` to a `&str`.
51     ///
52     /// # Examples
53     ///
54     /// ```
55     /// use ylong_http::version::Version;
56     ///
57     /// assert_eq!(Version::HTTP1_1.as_str(), "HTTP/1.1");
58     /// ```
as_str(&self) -> &str59     pub fn as_str(&self) -> &str {
60         match self.0 {
61             Inner::Http11 => "HTTP/1.1",
62             Inner::Http2 => "HTTP/2.0",
63             Inner::Http3 => "HTTP/3.0",
64         }
65     }
66 }
67 
68 impl<'a> TryFrom<&'a str> for Version {
69     type Error = HttpError;
70 
try_from(str: &'a str) -> Result<Self, Self::Error>71     fn try_from(str: &'a str) -> Result<Self, Self::Error> {
72         match str {
73             "HTTP/1.1" => Ok(Version::HTTP1_1),
74             "HTTP/2.0" => Ok(Version::HTTP2),
75             "HTTP/3.0" => Ok(Version::HTTP3),
76             _ => Err(ErrorKind::InvalidInput.into()),
77         }
78     }
79 }
80 
81 #[derive(Clone, Debug, PartialEq, Eq)]
82 enum Inner {
83     Http11,
84     Http2,
85     Http3,
86 }
87 
88 #[cfg(test)]
89 mod ut_version {
90     use std::convert::TryFrom;
91 
92     use super::Version;
93 
94     /// UT test cases for `Version::as_str`.
95     ///
96     /// # Brief
97     /// 1. Checks whether `Version::as_str` is correct.
98     #[test]
ut_version_as_str()99     fn ut_version_as_str() {
100         assert_eq!(Version::HTTP1_1.as_str(), "HTTP/1.1");
101         assert_eq!(Version::HTTP2.as_str(), "HTTP/2.0");
102         assert_eq!(Version::HTTP3.as_str(), "HTTP/3.0");
103     }
104 
105     /// UT test cases for `Version::try_from`.
106     ///
107     /// # Brief
108     /// 1. Checks whether `Version::try_from` is correct.
109     #[test]
ut_version_try_from()110     fn ut_version_try_from() {
111         assert_eq!(Version::try_from("HTTP/1.1").unwrap(), Version::HTTP1_1);
112         assert_eq!(Version::try_from("HTTP/2.0").unwrap(), Version::HTTP2);
113         assert_eq!(Version::try_from("HTTP/3.0").unwrap(), Version::HTTP3);
114         assert!(Version::try_from("http/1.1").is_err());
115         assert!(Version::try_from("http/2.0").is_err());
116         assert!(Version::try_from("http/3.0").is_err());
117     }
118 }
119