wechat_minapp/client/
token_type.rs1use super::access_token::AccessTokenBuilder;
14use super::{AccessToken, AppConfig, HttpClient};
15use crate::utils::build_request;
16use crate::{Result, constants};
17use async_trait::async_trait;
18use http::Method;
19use std::sync::Arc;
20use tracing::debug;
21
22#[async_trait]
24pub trait TokenType: Send + Sync {
25 async fn token(&self) -> Result<AccessToken>;
27 fn app_config(&self) -> AppConfig;
29}
30
31#[derive(Clone)]
34pub struct StableToken {
35 pub app_id: String,
36 pub secret: String,
37 pub end_point: String,
38 pub force_refresh: bool,
39 client: Arc<dyn HttpClient>,
40}
41
42impl StableToken {
43 pub fn new(
44 app_id: &str,
45 secret: &str,
46 force_refresh: bool,
47 client: Arc<dyn HttpClient>,
48 ) -> Self {
49 StableToken {
50 app_id: app_id.to_string(),
51 secret: secret.to_string(),
52 end_point: constants::STABLE_ACCESS_TOKEN_END_POINT.to_string(),
53 force_refresh,
54 client,
55 }
56 }
57}
58
59#[async_trait]
61impl TokenType for StableToken {
62 async fn token(&self) -> Result<AccessToken> {
64 let body = serde_json::json!({
65 "grant_type":"client_credential",
66 "appid":self.app_id.to_string(),
67 "secret":self.secret.to_string(),
68 "force_refresh":self.force_refresh,
69 });
70 let request = build_request(&self.end_point, Method::POST, None, None, Some(body))?;
71
72 let response = self.client.execute(request).await?;
73 let response_body = response.into_body();
74 let token_builder = serde_json::from_slice::<AccessTokenBuilder>(&response_body)?;
75 let token = token_builder.build();
76 debug!("stable access token :{:?}", token);
77 Ok(token)
78 }
79
80 fn app_config(&self) -> AppConfig {
82 AppConfig {
83 app_id: self.app_id.clone(),
84 secret: self.secret.clone(),
85 }
86 }
87}
88
89pub struct NonStableToken {
92 pub app_id: String,
93 pub secret: String,
94 pub end_point: String,
95 client: Arc<dyn HttpClient>,
96}
97
98impl NonStableToken {
99 pub fn new(app_id: &str, secret: &str, client: Arc<dyn HttpClient>) -> Self {
100 NonStableToken {
101 app_id: app_id.to_string(),
102 secret: secret.to_string(),
103 end_point: constants::ACCESS_TOKEN_END_POINT.to_string(),
104 client,
105 }
106 }
107}
108
109#[async_trait]
111impl TokenType for NonStableToken {
112 async fn token(&self) -> Result<AccessToken> {
114 let body = serde_json::json!({
115 "grant_type":"client_credential",
116 "appid":self.app_id.to_string(),
117 "secret":self.secret.to_string(),
118 });
119 let request = build_request(&self.end_point, Method::POST, None, None, Some(body))?;
120
121 let response = self.client.execute(request).await?;
122 let response_body = response.into_body();
123 let token_builder = serde_json::from_slice::<AccessTokenBuilder>(&response_body)?;
124 Ok(token_builder.build())
125 }
126
127 fn app_config(&self) -> AppConfig {
129 AppConfig {
130 app_id: self.app_id.clone(),
131 secret: self.secret.clone(),
132 }
133 }
134}