matrix_appservice_rs/
request.rs

1use std::collections::HashMap;
2
3use ruma::identifiers::UserId;
4use ruma_client::{Client, HttpClient, ResponseResult};
5
6use hyper::Uri;
7
8/// A builder for a request to the Matrix homeserver.
9#[derive(Debug, Clone)]
10pub struct RequestBuilder<'a, C, R>
11where
12    C: HttpClient,
13    R: ruma::api::OutgoingRequest,
14{
15    client: &'a Client<C>,
16    request: R,
17
18    params: HashMap<String, String>,
19}
20
21impl<'a, C, R> RequestBuilder<'a, C, R>
22where
23    C: HttpClient,
24    R: ruma::api::OutgoingRequest,
25{
26    /// Create a new `RequestBuilder`, with the given `Client` and the given `request`.
27    pub fn new(client: &'a Client<C>, request: R) -> Self {
28        Self {
29            client,
30            request,
31
32            params: HashMap::new(),
33        }
34    }
35
36    /// Set the `user_id` url parameter, returning the current builder to allow method chaining.
37    pub fn user_id(&mut self, user_id: &UserId) -> &mut Self {
38        self.params
39            .insert(String::from("user_id"), user_id.to_string());
40        self
41    }
42
43    /// Set the `ts` url parameter, returning the current builder to allow method chaining.
44    pub fn timestamp(&mut self, timestamp: i64) -> &mut Self {
45        self.params
46            .insert(String::from("ts"), timestamp.to_string());
47        self
48    }
49
50    /// Set the `access_token` url parameter, returning the current builder to allow method
51    /// chaining.
52    pub fn access_token(&mut self, access_token: String) -> &mut Self {
53        self.params
54            .insert(String::from("access_token"), access_token);
55        self
56    }
57
58    /// Submit the request, waiting on the response.
59    /// This will consume the current builder.
60    pub async fn request(self) -> ResponseResult<C, R> {
61        let mut new_params = String::new();
62        for (i, s) in self
63            .params
64            .into_iter()
65            .map(|(k, v)| format!("{}={}", k, v))
66            .enumerate()
67        {
68            if i > 0 {
69                new_params.push('&');
70            }
71            new_params.push_str(&s);
72        }
73
74        self.client
75            .send_customized_request(self.request, |req| {
76                let uri = req.uri_mut();
77                let new_path_and_query = match uri.query() {
78                    Some(params) => format!("{}?{}&{}", uri.path(), params, new_params),
79                    None => format!("{}?{}", uri.path(), new_params),
80                };
81
82                let mut parts = uri.clone().into_parts();
83                parts.path_and_query = Some(new_path_and_query.parse()?);
84                *uri = Uri::from_parts(parts)?;
85
86                Ok(())
87            })
88            .await
89    }
90}