rust_wechat_core/
client.rs1use std::borrow::Borrow;
2use crate::{ServerError, WechatError};
3#[cfg(feature = "multipart")]
4use reqwest::multipart;
5use reqwest::{IntoUrl, Url};
6use serde::de::DeserializeOwned;
7use serde::{Deserialize, Serialize};
8
9pub trait ClientTrait {
10 fn access_token(&self) -> impl Future<Output = crate::Result<String>> + Send;
11 fn refresh_access_token(&mut self) -> impl Future<Output = crate::Result<()>> + Send;
12 fn http_client(&self) -> &reqwest::Client;
13 fn url_with_query<I, K, V>(&self, url: &str, queries: I) -> crate::Result<Url>
14 where
15 I: IntoIterator,
16 I::Item: Borrow<(K, V)>,
17 K: AsRef<str>,
18 V: AsRef<str>,
19 {
20 Ok(
21 Url::parse_with_params(url, queries)
22 .map_err(|err| WechatError::CommonError(err.to_string()))?,
23 )
24 }
25
26 fn authorized_url(&self, url: &str) -> impl Future<Output = crate::Result<Url>> + Send
27 where
28 Self: Sync,
29 {
30 async {
31 let access_token = self.access_token().await?;
32 self.url_with_query(url, &[("access_token", access_token)])
33 }
34 }
35
36 fn get_empty<R: DeserializeOwned, U: IntoUrl + Send, >(
37 &self,
38 url: U,
39 ) -> impl Future<Output = crate::Result<R>> + Send
40 where
41 Self: Sync,
42 {
43 async {
44 Ok(self
45 .http_client()
46 .get(url)
47 .send()
48 .await?
49 .json::<R>()
50 .await?)
51 }
52 }
53
54 fn get<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
55 &self,
56 url: U,
57 query: &T,
58 ) -> impl Future<Output = crate::Result<R>> + Send
59 where
60 Self: Sync,
61 {
62 async {
63 Ok(self
64 .http_client()
65 .get(url)
66 .query(query)
67 .send()
68 .await?
69 .json::<R>()
70 .await?)
71 }
72 }
73
74 fn post_empty<R: DeserializeOwned, U: IntoUrl + Send>(
75 &self,
76 url: U,
77 ) -> impl Future<Output = crate::Result<R>> + Send
78 where
79 Self: Sync,
80 {
81 async {
82 Ok(self
83 .http_client()
84 .post(url)
85 .send()
86 .await?
87 .json::<R>()
88 .await?)
89 }
90 }
91
92 fn post<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
93 &self,
94 url: U,
95 data: &T,
96 ) -> impl Future<Output = crate::Result<R>> + Send
97 where
98 Self: Sync,
99 {
100 async {
101 Ok(self
102 .http_client()
103 .post(url)
104 .form(data)
105 .send()
106 .await?
107 .json::<R>()
108 .await?)
109 }
110 }
111
112 #[cfg(feature = "multipart")]
113 fn upload<R: DeserializeOwned, U: IntoUrl + Send>(
114 &self,
115 url: U,
116 multipart: multipart::Form,
117 ) -> impl Future<Output = crate::Result<R>> + Send
118 where
119 Self: Sync,
120 {
121 async {
122 Ok(self
123 .http_client()
124 .post(url)
125 .multipart(multipart)
126 .send()
127 .await?
128 .json::<R>()
129 .await?)
130 }
131 }
132
133 #[cfg(feature = "multipart")]
134 fn upload_with<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
135 &self,
136 url: U,
137 data: &T,
138 multipart: multipart::Form,
139 ) -> impl Future<Output = crate::Result<R>> + Send
140 where
141 Self: Sync,
142 {
143 async {
144 Ok(self
145 .http_client()
146 .post(url)
147 .form(data)
148 .multipart(multipart)
149 .send()
150 .await?
151 .json::<R>()
152 .await?)
153 }
154 }
155
156 fn json<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
157 &self,
158 url: U,
159 data: &T,
160 ) -> impl Future<Output = crate::Result<R>> + Send
161 where
162 Self: Sync,
163 {
164 async {
165 Ok(self
166 .http_client()
167 .post(url)
168 .json(data)
169 .send()
170 .await?
171 .json::<R>()
172 .await?)
173 }
174 }
175
176 fn download<U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
177 &self,
178 url: U,
179 query: &T,
180 ) -> impl Future<Output = crate::Result<Vec<u8>>> + Send
181 where
182 Self: Sync,
183 {
184 async {
185 let response = self
186 .http_client()
187 .get(url)
188 .query(query)
189 .send()
190 .await?;
191
192 if response.status() == 200 {
193 Ok(response.bytes().await?.to_vec())
194 } else {
195 let res: ServerError = response.json().await?;
196 Err(WechatError::ServerError(res))
197 }
198 }
199 }
200}