inth_oauth2_async/token/
refresh.rs1use serde_json::Value;
2use std::time::{Duration, SystemTime};
3
4use crate::client::response::{FromResponse, ParseError};
5use crate::token::Lifetime;
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct Refresh {
10 refresh_token: String,
11 expires: SystemTime,
12}
13
14impl Refresh {
15 pub fn refresh_token(&self) -> &str { &self.refresh_token }
19
20 pub fn expires(&self) -> SystemTime { self.expires }
22}
23
24impl Lifetime for Refresh {
25 fn expired(&self) -> bool { self.expires < SystemTime::now() }
26}
27
28impl FromResponse for Refresh {
29 fn from_response(json: &Value) -> Result<Self, ParseError> {
30 let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?;
31
32 let refresh_token = obj.get("refresh_token")
33 .and_then(Value::as_str)
34 .ok_or(ParseError::ExpectedFieldType("refresh_token", "string"))?;
35 let expires_in = obj.get("expires_in")
36 .and_then(Value::as_i64)
37 .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?;
38
39 Ok(Refresh {
40 refresh_token: refresh_token.into(),
41 expires: SystemTime::now() + Duration::from_secs(expires_in.try_into().unwrap_or(0)),
42 })
43 }
44
45 fn from_response_inherit(json: &Value, prev: &Self) -> Result<Self, ParseError> {
46 let obj = json.as_object().ok_or(ParseError::ExpectedType("object"))?;
47
48 let refresh_token = obj.get("refresh_token")
49 .and_then(Value::as_str)
50 .or(Some(&prev.refresh_token))
51 .ok_or(ParseError::ExpectedFieldType("refresh_token", "string"))?;
52
53 let expires_in = obj.get("expires_in")
54 .and_then(Value::as_i64)
55 .ok_or(ParseError::ExpectedFieldType("expires_in", "i64"))?;
56
57 Ok(Refresh {
58 refresh_token: refresh_token.into(),
59 expires: SystemTime::now() + Duration::from_secs(expires_in.try_into().unwrap_or(0)),
60 })
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn from_response() {
70 let json = r#"{"refresh_token":"aaaaaaaa","expires_in":3600}"#.parse().unwrap();
71 let refresh = Refresh::from_response(&json).unwrap();
72 assert_eq!("aaaaaaaa", refresh.refresh_token);
73 assert!(refresh.expires > SystemTime::now());
74 assert!(refresh.expires <= SystemTime::now() + Duration::from_secs(3600));
75 }
76
77 #[test]
78 fn from_response_inherit() {
79 let json = r#"{"expires_in":3600}"#.parse().unwrap();
80 let prev = Refresh {
81 refresh_token: String::from("aaaaaaaa"),
82 expires: SystemTime::now(),
83 };
84 let refresh = Refresh::from_response_inherit(&json, &prev).unwrap();
85 assert_eq!("aaaaaaaa", refresh.refresh_token);
86 assert!(refresh.expires > SystemTime::now());
87 assert!(refresh.expires <= SystemTime::now() + Duration::from_secs(3600));
88 }
89}