wechat_minapp/client/
access_token.rs1use chrono::{DateTime, Duration, Utc};
2use serde::{Deserialize, Deserializer, Serialize};
3
4#[derive(Clone, Serialize)]
5pub struct AccessToken {
6 pub access_token: String,
7 pub expired_at: DateTime<Utc>,
8}
9
10impl std::fmt::Debug for AccessToken {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 f.debug_struct("AccessToken")
13 .field("access_token", &"********")
14 .field("expired_at", &self.expired_at)
15 .finish()
16 }
17}
18
19#[derive(Deserialize)]
20pub(crate) struct AccessTokenBuilder {
21 pub access_token: String,
22 #[serde(
23 deserialize_with = "AccessTokenBuilder::deserialize_expired_at",
24 rename = "expires_in"
25 )]
26 pub expired_at: DateTime<Utc>,
27}
28
29impl AccessTokenBuilder {
30 fn deserialize_expired_at<'de, D>(
31 deserializer: D,
32 ) -> std::result::Result<DateTime<Utc>, D::Error>
33 where
34 D: Deserializer<'de>,
35 {
36 let seconds = Duration::seconds(i64::deserialize(deserializer)?);
37
38 Ok(Utc::now() + seconds)
39 }
40}
41
42impl std::fmt::Debug for AccessTokenBuilder {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 f.debug_struct("AccessTokenBuilder")
45 .field("access_token", &"********")
46 .field("expired_at", &self.expired_at)
47 .finish()
48 }
49}
50
51impl AccessTokenBuilder {
52 pub fn build(self) -> AccessToken {
53 AccessToken {
54 access_token: self.access_token,
55 expired_at: self.expired_at,
56 }
57 }
58}
59
60pub(crate) fn is_token_expired(token: &AccessToken) -> bool {
64 let now = Utc::now();
66 token.expired_at.signed_duration_since(now) < Duration::minutes(5)
67}