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