use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SessionMeta {
pub id: String,
pub title: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
#[serde(default = "default_version")]
pub version: u32,
#[serde(default)]
pub sequence: u64,
}
const fn default_version() -> u32 {
1
}
impl SessionMeta {
#[must_use]
pub fn new(
id: impl Into<String>,
title: impl Into<String>,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
) -> Self {
Self {
id: id.into(),
title: title.into(),
created_at,
updated_at,
version: default_version(),
sequence: 0,
}
}
#[must_use]
pub const fn with_version(mut self, version: u32) -> Self {
self.version = version;
self
}
#[must_use]
pub const fn with_sequence(mut self, sequence: u64) -> Self {
self.sequence = sequence;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serialization_roundtrip() {
let meta = SessionMeta {
id: "20250315_120000".to_string(),
title: "Test session".to_string(),
created_at: DateTime::from_timestamp(1_710_500_000, 0).unwrap().to_utc(),
updated_at: DateTime::from_timestamp(1_710_500_100, 0).unwrap().to_utc(),
version: 1,
sequence: 0,
};
let json = serde_json::to_string(&meta).unwrap();
let deserialized: SessionMeta = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized, meta);
}
#[test]
fn partial_eq_works() {
let a = SessionMeta {
id: "a".to_string(),
title: "Session A".to_string(),
created_at: DateTime::from_timestamp(100, 0).unwrap().to_utc(),
updated_at: DateTime::from_timestamp(200, 0).unwrap().to_utc(),
version: 1,
sequence: 0,
};
let b = a.clone();
assert_eq!(a, b);
}
}