webfinger_rs/
reqwest.rs

1use http::Uri;
2use tracing::trace;
3
4use crate::{error::Error, WebFingerRequest, WebFingerResponse};
5
6struct EmptyBody;
7
8impl From<EmptyBody> for reqwest::Body {
9    fn from(_: EmptyBody) -> reqwest::Body {
10        reqwest::Body::default()
11    }
12}
13
14impl TryFrom<&WebFingerRequest> for http::Request<EmptyBody> {
15    type Error = http::Error;
16
17    fn try_from(query: &WebFingerRequest) -> Result<http::Request<EmptyBody>, http::Error> {
18        let uri = Uri::try_from(query)?;
19        http::Request::builder()
20            .method("GET")
21            .uri(uri)
22            .body(EmptyBody)
23    }
24}
25
26impl TryFrom<&WebFingerRequest> for reqwest::Request {
27    type Error = crate::Error;
28
29    fn try_from(query: &WebFingerRequest) -> Result<reqwest::Request, crate::Error> {
30        let request = http::Request::try_from(query)?;
31        let request = reqwest::Request::try_from(request)?;
32        Ok(request)
33    }
34}
35
36impl WebFingerRequest {
37    /// Executes the WebFinger request.
38    ///
39    /// # Examples
40    ///
41    /// ```rust
42    /// use webfinger_rs::WebFingerRequest;
43    ///
44    /// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
45    /// let query = WebFingerRequest::builder("acct:carol@example.com")?
46    ///     .host("example.com")
47    ///     .rel("http://webfinger.net/rel/profile-page")
48    ///     .build();
49    /// let response = query.execute_reqwest().await?;
50    /// # Ok(())
51    /// # }
52    /// ```
53    #[tracing::instrument]
54    pub async fn execute_reqwest(&self) -> Result<WebFingerResponse, Error> {
55        let client = reqwest::Client::new();
56        self.execute_reqwest_with_client(&client).await
57    }
58
59    /// Executes the WebFinger request with a custom reqwest client.
60    #[tracing::instrument]
61    pub async fn execute_reqwest_with_client(
62        &self,
63        client: &reqwest::Client,
64    ) -> Result<WebFingerResponse, Error> {
65        let request = self.try_into()?;
66        trace!("request: {:?}", request);
67        let response = client.execute(request).await?;
68        trace!("response: {:?}", response);
69        async_convert::TryFrom::try_from(response).await
70    }
71
72    /// Converts the WebFinger request into a reqwest request.
73    pub fn try_into_reqwest(&self) -> Result<reqwest::Request, Error> {
74        self.try_into()
75    }
76}
77
78impl WebFingerResponse {
79    /// Converts a reqwest response into a WebFinger response.
80    pub async fn try_from_reqwest(response: reqwest::Response) -> Result<WebFingerResponse, Error> {
81        async_convert::TryFrom::try_from(response).await
82    }
83}
84
85#[async_convert::async_trait]
86impl async_convert::TryFrom<reqwest::Response> for WebFingerResponse {
87    type Error = crate::Error;
88
89    async fn try_from(response: reqwest::Response) -> Result<WebFingerResponse, crate::Error> {
90        let response = response.error_for_status()?;
91        let response = response.json().await?;
92        Ok(response)
93    }
94}