web_faith/request/
target.rs1use bytes::Bytes;
4use url::Url;
5
6use crate::{
7 error::{FaithError, FaithErrorKind},
8 request::{Request, RequestBody, RequestOptions},
9};
10
11pub enum Target {
17 Url(Url),
19 Request(Box<Request>),
21}
22
23impl From<Url> for Target {
24 fn from(url: Url) -> Self {
25 Self::Url(url)
26 }
27}
28
29impl From<Request> for Target {
30 fn from(request: Request) -> Self {
31 Self::Request(Box::new(request))
32 }
33}
34
35impl TryFrom<&str> for Target {
39 type Error = FaithError;
40
41 fn try_from(url: &str) -> Result<Self, Self::Error> {
42 Url::parse(url)
43 .map(Self::Url)
44 .map_err(|_| FaithErrorKind::InvalidUrl.into())
45 }
46}
47
48impl TryFrom<String> for Target {
49 type Error = FaithError;
50
51 fn try_from(url: String) -> Result<Self, Self::Error> {
52 Self::try_from(url.as_str())
53 }
54}
55
56impl<B> TryFrom<http::Request<B>> for Target
60where
61 B: Into<Bytes>,
62{
63 type Error = FaithError;
64
65 fn try_from(request: http::Request<B>) -> Result<Self, Self::Error> {
66 let (parts, body) = request.into_parts();
67
68 let url = Url::parse(&parts.uri.to_string())
69 .map_err(|_| FaithError::from(FaithErrorKind::InvalidUrl))?;
70
71 let mut headers = Vec::new();
72 for (name, value) in parts.headers.iter() {
73 let Ok(value) = value.to_str() else {
74 return Err(FaithErrorKind::InvalidHeader.into());
75 };
76 headers.push((name.to_string(), value.to_owned()));
77 }
78
79 let body = body.into();
80 Ok(Self::Request(Box::new(Request {
81 url,
82 options: RequestOptions {
83 method: Some(parts.method.to_string()),
84 headers: (!headers.is_empty()).then_some(headers),
85 ..RequestOptions::default()
86 },
87 body: if body.is_empty() {
88 RequestBody::None
89 } else {
90 RequestBody::Bytes(body)
91 },
92 })))
93 }
94}