1 use crate::p3::bindings::http::types::{ErrorCode, Method, Scheme};
2 use core::convert::Infallible;
3 use core::error::Error as _;
4 use tracing::warn;
5 
6 impl From<Infallible> for ErrorCode {
from(x: Infallible) -> Self7     fn from(x: Infallible) -> Self {
8         match x {}
9     }
10 }
11 
12 impl ErrorCode {
13     /// Translate a [`hyper::Error`] to a wasi-http [ErrorCode] in the context of a request.
from_hyper_request_error(err: hyper::Error) -> Self14     pub fn from_hyper_request_error(err: hyper::Error) -> Self {
15         // If there's a source, we might be able to extract a wasi-http error from it.
16         if let Some(cause) = err.source() {
17             if let Some(err) = cause.downcast_ref::<Self>() {
18                 return err.clone();
19             }
20         }
21 
22         warn!("hyper request error: {err:?}");
23 
24         Self::HttpProtocolError
25     }
26 
27     /// Translate a [`hyper::Error`] to a wasi-http [ErrorCode] in the context of a response.
28     #[cfg(feature = "default-send-request")]
from_hyper_response_error(err: hyper::Error) -> Self29     pub(crate) fn from_hyper_response_error(err: hyper::Error) -> Self {
30         if err.is_timeout() {
31             return ErrorCode::HttpResponseTimeout;
32         }
33 
34         // If there's a source, we might be able to extract a wasi-http error from it.
35         if let Some(cause) = err.source() {
36             if let Some(err) = cause.downcast_ref::<Self>() {
37                 return err.clone();
38             }
39         }
40 
41         warn!("hyper response error: {err:?}");
42 
43         ErrorCode::HttpProtocolError
44     }
45 }
46 
47 impl From<http::Method> for Method {
from(method: http::Method) -> Self48     fn from(method: http::Method) -> Self {
49         Self::from(&method)
50     }
51 }
52 
53 impl From<&http::Method> for Method {
from(method: &http::Method) -> Self54     fn from(method: &http::Method) -> Self {
55         if method == http::Method::GET {
56             Self::Get
57         } else if method == http::Method::HEAD {
58             Self::Head
59         } else if method == http::Method::POST {
60             Self::Post
61         } else if method == http::Method::PUT {
62             Self::Put
63         } else if method == http::Method::DELETE {
64             Self::Delete
65         } else if method == http::Method::CONNECT {
66             Self::Connect
67         } else if method == http::Method::OPTIONS {
68             Self::Options
69         } else if method == http::Method::TRACE {
70             Self::Trace
71         } else if method == http::Method::PATCH {
72             Self::Patch
73         } else {
74             Self::Other(method.as_str().into())
75         }
76     }
77 }
78 
79 impl TryFrom<Method> for http::Method {
80     type Error = http::method::InvalidMethod;
81 
try_from(method: Method) -> Result<Self, Self::Error>82     fn try_from(method: Method) -> Result<Self, Self::Error> {
83         Self::try_from(&method)
84     }
85 }
86 
87 impl TryFrom<&Method> for http::Method {
88     type Error = http::method::InvalidMethod;
89 
try_from(method: &Method) -> Result<Self, Self::Error>90     fn try_from(method: &Method) -> Result<Self, Self::Error> {
91         match method {
92             Method::Get => Ok(Self::GET),
93             Method::Head => Ok(Self::HEAD),
94             Method::Post => Ok(Self::POST),
95             Method::Put => Ok(Self::PUT),
96             Method::Delete => Ok(Self::DELETE),
97             Method::Connect => Ok(Self::CONNECT),
98             Method::Options => Ok(Self::OPTIONS),
99             Method::Trace => Ok(Self::TRACE),
100             Method::Patch => Ok(Self::PATCH),
101             Method::Other(s) => s.parse(),
102         }
103     }
104 }
105 
106 impl From<http::uri::Scheme> for Scheme {
from(scheme: http::uri::Scheme) -> Self107     fn from(scheme: http::uri::Scheme) -> Self {
108         Self::from(&scheme)
109     }
110 }
111 
112 impl From<&http::uri::Scheme> for Scheme {
from(scheme: &http::uri::Scheme) -> Self113     fn from(scheme: &http::uri::Scheme) -> Self {
114         if *scheme == http::uri::Scheme::HTTP {
115             Self::Http
116         } else if *scheme == http::uri::Scheme::HTTPS {
117             Self::Https
118         } else {
119             Self::Other(scheme.as_str().into())
120         }
121     }
122 }
123 
124 impl TryFrom<Scheme> for http::uri::Scheme {
125     type Error = http::uri::InvalidUri;
126 
try_from(scheme: Scheme) -> Result<Self, Self::Error>127     fn try_from(scheme: Scheme) -> Result<Self, Self::Error> {
128         Self::try_from(&scheme)
129     }
130 }
131 
132 impl TryFrom<&Scheme> for http::uri::Scheme {
133     type Error = http::uri::InvalidUri;
134 
try_from(scheme: &Scheme) -> Result<Self, Self::Error>135     fn try_from(scheme: &Scheme) -> Result<Self, Self::Error> {
136         match scheme {
137             Scheme::Http => Ok(Self::HTTP),
138             Scheme::Https => Ok(Self::HTTPS),
139             Scheme::Other(s) => s.parse(),
140         }
141     }
142 }
143