1use reqwest::{multipart::Form, Error, Response};
2use serde_json::Value;
3use std::time::Duration;
4use twapi_oauth::oauth2_authorization_header;
5
6pub struct Client {
7 bearer_token: String,
8 timeout_sec: Option<Duration>,
9}
10
11impl Client {
12 pub fn new(bearer_token: &str, timeout_sec: Option<Duration>) -> Self {
13 Self {
14 bearer_token: bearer_token.to_owned(),
15 timeout_sec,
16 }
17 }
18
19 pub async fn new_from_key(
20 consumer_key: &str,
21 consumer_secret: &str,
22 timeout_sec: Option<Duration>,
23 ) -> Result<Option<Self>, Error> {
24 Ok(
25 crate::oauth::get_bearer_token(&consumer_key, &consumer_secret, timeout_sec)
26 .await?
27 .map(|bearer_token| Self::new(&bearer_token, None)),
28 )
29 }
30
31 pub async fn new_by_env(timeout_sec: Option<Duration>) -> Result<Option<Self>, Error> {
32 let consumer_key = match std::env::var("CONSUMER_KEY") {
33 Ok(consumer_key) => consumer_key,
34 Err(_) => return Ok(None),
35 };
36 let consumer_secret = match std::env::var("CONSUMER_SECRET") {
37 Ok(consumer_key) => consumer_key,
38 Err(_) => return Ok(None),
39 };
40 Self::new_from_key(&consumer_key, &consumer_secret, timeout_sec).await
41 }
42
43 fn make_header(&self) -> String {
44 oauth2_authorization_header(&self.bearer_token)
45 }
46
47 pub async fn get(
48 &self,
49 url: &str,
50 query_options: &Vec<(&str, &str)>,
51 ) -> Result<Response, Error> {
52 crate::raw::get(url, query_options, &self.make_header(), self.timeout_sec).await
53 }
54
55 pub async fn post(
56 &self,
57 url: &str,
58 query_options: &Vec<(&str, &str)>,
59 form_options: &Vec<(&str, &str)>,
60 ) -> Result<Response, Error> {
61 crate::raw::post(
62 url,
63 query_options,
64 form_options,
65 &self.make_header(),
66 self.timeout_sec,
67 )
68 .await
69 }
70
71 pub async fn json(
72 &self,
73 url: &str,
74 query_options: &Vec<(&str, &str)>,
75 data: &Value,
76 ) -> Result<Response, Error> {
77 crate::raw::json(
78 url,
79 query_options,
80 data,
81 &self.make_header(),
82 self.timeout_sec,
83 )
84 .await
85 }
86
87 pub async fn put(
88 &self,
89 url: &str,
90 query_options: &Vec<(&str, &str)>,
91 ) -> Result<Response, Error> {
92 crate::raw::put(url, query_options, &self.make_header(), self.timeout_sec).await
93 }
94
95 pub async fn delete(
96 &self,
97 url: &str,
98 query_options: &Vec<(&str, &str)>,
99 ) -> Result<Response, Error> {
100 crate::raw::delete(url, query_options, &self.make_header(), self.timeout_sec).await
101 }
102
103 pub async fn multipart(
104 &self,
105 url: &str,
106 query_options: &Vec<(&str, &str)>,
107 data: Form,
108 ) -> Result<Response, Error> {
109 crate::raw::multipart(
110 url,
111 query_options,
112 data,
113 &self.make_header(),
114 self.timeout_sec,
115 )
116 .await
117 }
118}
119
120pub async fn get(
121 url: &str,
122 query_options: &Vec<(&str, &str)>,
123 bearer_token: &str,
124 timeout_sec: Option<Duration>,
125) -> Result<Response, Error> {
126 let client = Client::new(bearer_token, timeout_sec);
127 client.get(url, query_options).await
128}
129
130pub async fn post(
131 url: &str,
132 query_options: &Vec<(&str, &str)>,
133 form_options: &Vec<(&str, &str)>,
134 bearer_token: &str,
135 timeout_sec: Option<Duration>,
136) -> Result<Response, Error> {
137 let client = Client::new(bearer_token, timeout_sec);
138 client.post(url, query_options, form_options).await
139}
140
141pub async fn json(
142 url: &str,
143 query_options: &Vec<(&str, &str)>,
144 data: &Value,
145 bearer_token: &str,
146 timeout_sec: Option<Duration>,
147) -> Result<Response, Error> {
148 let client = Client::new(bearer_token, timeout_sec);
149 client.json(url, query_options, data).await
150}
151
152pub async fn put(
153 url: &str,
154 query_options: &Vec<(&str, &str)>,
155 bearer_token: &str,
156 timeout_sec: Option<Duration>,
157) -> Result<Response, Error> {
158 let client = Client::new(bearer_token, timeout_sec);
159 client.put(url, query_options).await
160}
161
162pub async fn delete(
163 url: &str,
164 query_options: &Vec<(&str, &str)>,
165 bearer_token: &str,
166 timeout_sec: Option<Duration>,
167) -> Result<Response, Error> {
168 let client = Client::new(bearer_token, timeout_sec);
169 client.delete(url, query_options).await
170}
171
172pub async fn multipart(
173 url: &str,
174 query_options: &Vec<(&str, &str)>,
175 data: Form,
176 bearer_token: &str,
177 timeout_sec: Option<Duration>,
178) -> Result<Response, Error> {
179 let client = Client::new(bearer_token, timeout_sec);
180 client.multipart(url, query_options, data).await
181}
182
183#[cfg(test)]
184mod tests {
185 use crate::*;
186 use serde_json::Value;
187 use std::env;
188
189 #[tokio::test]
190 async fn test_api() {
191 let consumer_key = env::var("CONSUMER_KEY").unwrap();
192 let consumer_secret = env::var("CONSUMER_SECRET").unwrap();
193 let bearer_token = oauth::get_bearer_token(&consumer_key, &consumer_secret, None)
194 .await
195 .unwrap()
196 .unwrap();
197
198 let res: Value = v2::get(
200 "https://api.twitter.com/1.1/search/tweets.json",
201 &vec![("q", "*abc"), ("count", "2")],
202 &bearer_token,
203 None,
204 )
205 .await
206 .unwrap()
207 .json()
208 .await
209 .unwrap();
210 println!("{:?}", res);
211 }
212}