use chrono::{DateTime, TimeDelta, Utc, serde::ts_seconds_option};
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Token {
pub access_token: String,
pub token_type: String,
pub expires_in: u16,
#[serde(default)]
#[serde(with = "ts_seconds_option")]
pub expires_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_token: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
}
impl Token {
pub fn is_expired(&self) -> bool {
self.expires_at
.is_none_or(|expires_at| Utc::now() + TimeDelta::seconds(10) >= expires_at)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn token() {
let json = r#"
{
"access_token": "string",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "string",
"scope": "user-read-email user-read-private"
}
"#;
crate::test::assert_deserialized!(Token, json);
}
}