wechat_minapp/client/
token_type.rs1use super::access_token::AccessTokenBuilder;
14use super::{AccessToken, AppConfig, HttpClient};
15use crate::utils::MpResponse;
16use crate::utils::build_request;
17use crate::{Result, constants};
18use async_trait::async_trait;
19use http::Method;
20use std::sync::Arc;
21use tracing::debug;
22
23#[async_trait]
25pub trait TokenType: Send + Sync {
26 async fn token(&self) -> Result<AccessToken>;
28 fn app_config(&self) -> AppConfig;
30}
31
32#[derive(Clone)]
35pub struct StableToken {
36 pub app_id: String,
37 pub secret: String,
38 pub end_point: String,
39 pub force_refresh: bool,
40 client: Arc<dyn HttpClient>,
41}
42
43impl StableToken {
44 pub fn new(
45 app_id: &str,
46 secret: &str,
47 force_refresh: bool,
48 client: Arc<dyn HttpClient>,
49 ) -> Self {
50 StableToken {
51 app_id: app_id.to_string(),
52 secret: secret.to_string(),
53 end_point: constants::STABLE_ACCESS_TOKEN_END_POINT.to_string(),
54 force_refresh,
55 client,
56 }
57 }
58}
59
60#[async_trait]
62impl TokenType for StableToken {
63 async fn token(&self) -> Result<AccessToken> {
65 let body = serde_json::json!({
66 "grant_type":"client_credential",
67 "appid":self.app_id.to_string(),
68 "secret":self.secret.to_string(),
69 "force_refresh":self.force_refresh,
70 });
71 let request = build_request(&self.end_point, Method::POST, None, None, Some(body))?;
72
73 let response = self.client.execute(request).await?;
74 let response_body = response.into_body();
75 let token_builder =
76 serde_json::from_slice::<MpResponse<AccessTokenBuilder>>(&response_body)?;
77 let token = token_builder.extract()?;
79 let token = token.build();
80 debug!("stable access token :{:?}", token);
81 Ok(token)
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 body = serde_json::json!({
119 "grant_type":"client_credential",
120 "appid":self.app_id.to_string(),
121 "secret":self.secret.to_string(),
122 });
123 let request = build_request(&self.end_point, Method::POST, None, None, Some(body))?;
124
125 let response = self.client.execute(request).await?;
126 let response_body = response.into_body();
127 let token_builder =
128 serde_json::from_slice::<MpResponse<AccessTokenBuilder>>(&response_body)?;
129 let token = token_builder.extract()?;
131 let token = token.build();
132 Ok(token)
133 }
136
137 fn app_config(&self) -> AppConfig {
139 AppConfig {
140 app_id: self.app_id.clone(),
141 secret: self.secret.clone(),
142 }
143 }
144}