rust_wechat_core/
client.rs

1use 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}