pub(crate) mod transform;
use std::fmt::{Display, Formatter};
use chrono::{DateTime, Utc};
use serde::Serialize;
use crate::model::info::{KeyInfo, UserAttributeInfo, UserInfo};
#[derive(Debug, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Status {
Valid {
#[serde(skip_serializing_if = "Option::is_none")]
expires: Option<DateTime<Utc>>,
},
Expired {
time: DateTime<Utc>,
},
RevokedSoft {
time: DateTime<Utc>,
reason: String,
},
RevokedHard {
time: DateTime<Utc>,
reason: String,
},
Invalid {
context: String,
},
}
impl Status {
pub fn is_valid(&self) -> bool {
matches!(self, Status::Valid { .. })
}
pub fn is_revoked(&self) -> bool {
matches!(
self,
Status::RevokedSoft { .. } | Status::RevokedHard { .. }
)
}
}
impl Display for Status {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Status::Valid { expires: None } => write!(f, "✅ Active (no expiration)"),
Status::Valid { expires: Some(exp) } => write!(f, "✅ Active, expires {exp}"),
Status::Expired { time } => write!(f, "🚫 Expired {time}"),
Status::RevokedSoft { time, reason: msg } => {
write!(f, "🚫 Revoked (soft) {time}: {msg}")
}
Status::RevokedHard { time, reason: msg } => {
write!(f, "🚫 Revoked (hard) {time}: {msg}")
}
Status::Invalid { context } => write!(f, "🚫 Invalid: {context}"),
}
}
}
#[derive(Debug)]
pub(crate) struct CertStatus {
pub(crate) primary: (KeyInfo, Status, Option<Vec<String>>),
pub(crate) subkeys: Vec<(KeyInfo, Status, Option<Vec<String>>)>,
pub(crate) users: Vec<(UserInfo, Status, bool)>,
pub(crate) user_attributes: Vec<(UserAttributeInfo, Status, bool)>,
}