twitter_client/
request.rs1use http::header::{HeaderValue, AUTHORIZATION, CONTENT_TYPE};
2use http::{Method, Uri};
3use oauth_credentials::Token;
4use serde::de;
5
6use crate::response::{RawResponseFuture, ResponseFuture};
7use crate::traits::HttpService;
8
9pub trait RawRequest: oauth::Request {
10 fn method(&self) -> &Method;
11
12 fn uri(&self) -> &'static str;
13
14 fn send_raw<C, T, S, B>(
15 &self,
16 token: &Token<C, T>,
17 http: &mut S,
18 ) -> RawResponseFuture<S::Future>
19 where
20 C: AsRef<str>,
21 T: AsRef<str>,
22 S: HttpService<B>,
23 B: From<Vec<u8>>,
24 {
25 let req = prepare_request(self.method(), self.uri(), self, token.as_ref());
26 RawResponseFuture::new(http.call(req.map(Into::into)))
27 }
28}
29
30pub trait Request: RawRequest {
31 type Data: de::DeserializeOwned;
32
33 fn send<C, T, S, B>(
34 &self,
35 token: &Token<C, T>,
36 http: &mut S,
37 ) -> ResponseFuture<Self::Data, S::Future>
38 where
39 C: AsRef<str>,
40 T: AsRef<str>,
41 S: HttpService<B>,
42 B: From<Vec<u8>>,
43 {
44 self.send_raw(token, http).into()
45 }
46}
47
48fn prepare_request<R>(
49 method: &Method,
50 uri: &'static str,
51 req: &R,
52 token: Token<&str, &str>,
53) -> http::Request<Vec<u8>>
54where
55 R: oauth::Request + ?Sized,
56{
57 let form = method == Method::POST;
58
59 let mut oauth = oauth::Builder::new(token.client(), oauth::HmacSha1);
60 oauth.token(token.token());
61 let authorization = oauth.build(method.as_str(), uri, req);
62
63 let http = http::Request::builder()
64 .method(method)
65 .header(AUTHORIZATION, authorization);
66
67 if form {
68 let data = oauth::to_form_urlencoded(req).into_bytes();
69 http.uri(Uri::from_static(uri))
70 .header(
71 CONTENT_TYPE,
72 HeaderValue::from_static("application/x-www-form-urlencoded"),
73 )
74 .body(data)
75 .unwrap()
76 } else {
77 let uri = oauth::to_uri_query(uri.to_owned(), req);
78 http.uri(uri).body(Vec::default()).unwrap()
79 }
80}