use serde::{Deserialize, Serialize};
use crate::identity::CallerIdentity;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionContext {
pub session_id: String,
pub caller: CallerIdentity,
pub created_at: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expires_at: Option<u64>,
#[serde(default)]
pub request_count: u64,
#[serde(default)]
pub bytes_read: u64,
#[serde(default)]
pub bytes_written: u64,
#[serde(default)]
pub delegation_depth: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub metadata: Option<serde_json::Value>,
}
impl SessionContext {
#[must_use]
pub fn new(session_id: String, caller: CallerIdentity) -> Self {
let now = chrono::Utc::now().timestamp() as u64;
Self {
session_id,
caller,
created_at: now,
expires_at: None,
request_count: 0,
bytes_read: 0,
bytes_written: 0,
delegation_depth: 0,
metadata: None,
}
}
#[must_use]
pub fn is_expired(&self) -> bool {
if let Some(exp) = self.expires_at {
let now = chrono::Utc::now().timestamp() as u64;
now >= exp
} else {
false
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::identity::CallerIdentity;
#[test]
fn new_session_defaults() {
let session = SessionContext::new("sess-001".to_string(), CallerIdentity::anonymous());
assert_eq!(session.session_id, "sess-001");
assert_eq!(session.request_count, 0);
assert_eq!(session.bytes_read, 0);
assert_eq!(session.delegation_depth, 0);
assert!(session.expires_at.is_none());
}
#[test]
fn expired_session() {
let mut session = SessionContext::new("sess-002".to_string(), CallerIdentity::anonymous());
session.expires_at = Some(0); assert!(session.is_expired());
}
#[test]
fn not_expired_when_no_expiry() {
let session = SessionContext::new("sess-003".to_string(), CallerIdentity::anonymous());
assert!(!session.is_expired());
}
#[test]
fn serde_roundtrip() {
let session = SessionContext::new("sess-004".to_string(), CallerIdentity::anonymous());
let json = serde_json::to_string(&session).unwrap();
let back: SessionContext = serde_json::from_str(&json).unwrap();
assert_eq!(back.session_id, "sess-004");
}
}