webfinger_rs/
reqwest.rs

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