use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum HttpVersionError {
Unsupported,
}
impl fmt::Display for HttpVersionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Unsupported => write!(f, "unsupported HTTP version"),
}
}
}
impl std::error::Error for HttpVersionError {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HttpVersion {
Http10,
Http11,
}
impl HttpVersion {
pub fn parse(version_str: &str) -> Result<Self, HttpVersionError> {
match version_str {
"HTTP/1.0" => Ok(Self::Http10),
"HTTP/1.1" => Ok(Self::Http11),
_ => Err(HttpVersionError::Unsupported),
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Http10 => "HTTP/1.0",
Self::Http11 => "HTTP/1.1",
}
}
pub fn major(&self) -> u8 {
match self {
Self::Http10 => 1,
Self::Http11 => 1,
}
}
pub fn minor(&self) -> u8 {
match self {
Self::Http10 => 0,
Self::Http11 => 1,
}
}
}
impl fmt::Display for HttpVersion {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl AsRef<str> for HttpVersion {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl From<&hyper::http::Version> for HttpVersion {
fn from(v: &hyper::http::Version) -> Self {
match *v {
hyper::http::Version::HTTP_10 => Self::Http10,
hyper::http::Version::HTTP_11 => Self::Http11,
_ => Self::Http11, }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parse_http_1_0() {
assert_eq!(HttpVersion::parse("HTTP/1.0").unwrap(), HttpVersion::Http10);
}
#[test]
fn parse_http_1_1() {
assert_eq!(HttpVersion::parse("HTTP/1.1").unwrap(), HttpVersion::Http11);
}
#[test]
fn parse_unsupported() {
assert_eq!(
HttpVersion::parse("HTTP/2.0").unwrap_err(),
HttpVersionError::Unsupported
);
assert_eq!(
HttpVersion::parse("HTTP/0.9").unwrap_err(),
HttpVersionError::Unsupported
);
assert_eq!(
HttpVersion::parse("").unwrap_err(),
HttpVersionError::Unsupported
);
}
#[test]
fn as_str() {
assert_eq!(HttpVersion::Http10.as_str(), "HTTP/1.0");
assert_eq!(HttpVersion::Http11.as_str(), "HTTP/1.1");
}
#[test]
fn major_minor() {
assert_eq!(HttpVersion::Http10.major(), 1);
assert_eq!(HttpVersion::Http10.minor(), 0);
assert_eq!(HttpVersion::Http11.major(), 1);
assert_eq!(HttpVersion::Http11.minor(), 1);
}
#[test]
fn display() {
assert_eq!(format!("{}", HttpVersion::Http10), "HTTP/1.0");
assert_eq!(format!("{}", HttpVersion::Http11), "HTTP/1.1");
}
#[test]
fn as_ref_str() {
let s: &str = HttpVersion::Http11.as_ref();
assert_eq!(s, "HTTP/1.1");
}
#[test]
fn error_display() {
assert!(!HttpVersionError::Unsupported.to_string().is_empty());
}
#[test]
fn error_is_error() {
let err: &dyn std::error::Error = &HttpVersionError::Unsupported;
assert!(!err.to_string().is_empty());
}
}