wechat_minapp/client/
token_type.rs1use super::access_token::AccessTokenBuilder;
14use super::{AccessToken, AppConfig, HttpClient};
15use crate::{Result, constants};
16use async_trait::async_trait;
17use http::{Method, Request};
18use std::collections::HashMap;
19use std::sync::Arc;
20
21#[async_trait]
23pub trait TokenType: Send + Sync {
24 async fn token(&self) -> Result<AccessToken>;
26 fn app_config(&self) -> AppConfig;
28}
29
30#[derive(Clone)]
33pub struct StableToken {
34 pub app_id: String,
35 pub secret: String,
36 pub end_point: String,
37 pub force_refresh: bool,
38 client: Arc<dyn HttpClient>,
39}
40
41impl StableToken {
42 pub fn new(
43 app_id: &str,
44 secret: &str,
45 force_refresh: bool,
46 client: Arc<dyn HttpClient>,
47 ) -> Self {
48 StableToken {
49 app_id: app_id.to_string(),
50 secret: secret.to_string(),
51 end_point: constants::STABLE_ACCESS_TOKEN_END_POINT.to_string(),
52 force_refresh,
53 client,
54 }
55 }
56}
57
58#[async_trait]
60impl TokenType for StableToken {
61 async fn token(&self) -> Result<AccessToken> {
63 let mut body: HashMap<&str, String> = HashMap::new();
64 body.insert("grant_type", "client_credential".into());
65 body.insert("appid", self.app_id.to_string());
66 body.insert("secret", self.secret.to_string());
67
68 if self.force_refresh {
69 body.insert("force_refresh", self.force_refresh.to_string());
70 }
71 let req_body = serde_json::to_vec(&body)?;
72 let request = Request::builder()
73 .uri(self.end_point.clone())
74 .method(Method::POST)
75 .header("User-Agent", constants::HTTP_CLIENT_USER_AGENT)
76 .body(req_body)?;
77
78 let response = self.client.execute(request).await?;
79 let response_body = response.into_body();
80 let token_builder = serde_json::from_slice::<AccessTokenBuilder>(&response_body)?;
81 Ok(token_builder.build())
82 }
83
84 fn app_config(&self) -> AppConfig {
86 AppConfig {
87 app_id: self.app_id.clone(),
88 secret: self.secret.clone(),
89 }
90 }
91}
92
93pub struct NonStableToken {
96 pub app_id: String,
97 pub secret: String,
98 pub end_point: String,
99 client: Arc<dyn HttpClient>,
100}
101
102impl NonStableToken {
103 pub fn new(app_id: &str, secret: &str, client: Arc<dyn HttpClient>) -> Self {
104 NonStableToken {
105 app_id: app_id.to_string(),
106 secret: secret.to_string(),
107 end_point: constants::ACCESS_TOKEN_END_POINT.to_string(),
108 client,
109 }
110 }
111}
112
113#[async_trait]
115impl TokenType for NonStableToken {
116 async fn token(&self) -> Result<AccessToken> {
118 let mut body: HashMap<&str, String> = HashMap::new();
119 body.insert("grant_type", "client_credential".into());
120 body.insert("appid", self.app_id.to_string());
121 body.insert("secret", self.secret.to_string());
122
123 let req_body = serde_json::to_vec(&body)?;
124 let request = Request::builder()
125 .uri(self.end_point.clone())
126 .method(Method::POST)
127 .header("User-Agent", constants::HTTP_CLIENT_USER_AGENT)
128 .body(req_body)?;
129
130 let response = self.client.execute(request).await?;
131 let response_body = response.into_body();
132 let token_builder = serde_json::from_slice::<AccessTokenBuilder>(&response_body)?;
133 Ok(token_builder.build())
134 }
135
136 fn app_config(&self) -> AppConfig {
138 AppConfig {
139 app_id: self.app_id.clone(),
140 secret: self.secret.clone(),
141 }
142 }
143}