use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GrantTokenRequest {
#[serde(rename = "grant_type")]
pub grant_type: String,
pub app_key: String,
pub app_secret: String,
}
impl GrantTokenRequest {
#[must_use]
pub fn new(app_key: impl Into<String>, app_secret: impl Into<String>) -> Self {
Self {
grant_type: "client_credentials".to_string(),
app_key: app_key.into(),
app_secret: app_secret.into(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshTokenRequest {
pub grant_type: String,
pub app_key: String,
pub app_secret: String,
pub refresh_token: String,
}
impl RefreshTokenRequest {
#[must_use]
pub fn new(
app_key: impl Into<String>,
app_secret: impl Into<String>,
refresh_token: impl Into<String>,
) -> Self {
Self {
grant_type: "refresh_token".to_string(),
app_key: app_key.into(),
app_secret: app_secret.into(),
refresh_token: refresh_token.into(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenResponse {
#[serde(default)]
pub id_token: String,
#[serde(default)]
pub refresh_token: String,
#[serde(default)]
pub expires_in: u64,
#[serde(default)]
pub token_type: String,
}
impl TokenResponse {
#[must_use]
pub fn has_token(&self) -> bool {
!self.id_token.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn grant_token_request_serialises() {
let r = GrantTokenRequest::new("k", "s");
let j = serde_json::to_string(&r).unwrap();
assert!(j.contains("\"grant_type\":\"client_credentials\""));
assert!(j.contains("\"app_key\":\"k\""));
assert!(j.contains("\"app_secret\":\"s\""));
}
#[test]
fn refresh_token_request_serialises() {
let r = RefreshTokenRequest::new("k", "s", "rt");
let j = serde_json::to_string(&r).unwrap();
assert!(j.contains("\"grant_type\":\"refresh_token\""));
assert!(j.contains("\"refresh_token\":\"rt\""));
}
#[test]
fn token_response_parses_minimal_body() {
let body =
r#"{"id_token":"abc","refresh_token":"xyz","expires_in":3600,"token_type":"Bearer"}"#;
let r: TokenResponse = serde_json::from_str(body).unwrap();
assert_eq!(r.id_token, "abc");
assert_eq!(r.refresh_token, "xyz");
assert_eq!(r.expires_in, 3600);
assert!(r.has_token());
}
#[test]
fn token_response_handles_missing_fields() {
let r: TokenResponse = serde_json::from_str("{}").unwrap();
assert!(!r.has_token());
}
}