use crate::error::Result;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CardMetadata {
pub id: String,
pub compressed_size: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub original_size: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub profile: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub created: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dict_version: Option<String>,
}
impl CardMetadata {
pub fn new(id: impl Into<String>, compressed_size: u64) -> Self {
Self {
id: id.into(),
compressed_size,
original_size: None,
profile: None,
created: None,
dict_version: None,
}
}
pub fn with_original_size(mut self, size: u64) -> Self {
self.original_size = Some(size);
self
}
pub fn with_profile(mut self, profile: impl Into<String>) -> Self {
self.profile = Some(profile.into());
self
}
pub fn with_timestamp(mut self, timestamp: u64) -> Self {
self.created = Some(timestamp);
self
}
pub fn with_dict_version(mut self, version: impl Into<String>) -> Self {
self.dict_version = Some(version.into());
self
}
pub fn to_json(&self) -> Result<Vec<u8>> {
Ok(serde_json::to_vec(self)?)
}
pub fn from_json(bytes: &[u8]) -> Result<Self> {
Ok(serde_json::from_slice(bytes)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metadata_new() {
let metadata = CardMetadata::new("test::doc", 1234);
assert_eq!(metadata.id, "test::doc");
assert_eq!(metadata.compressed_size, 1234);
assert_eq!(metadata.original_size, None);
}
#[test]
fn test_metadata_builder() {
let metadata = CardMetadata::new("test::doc", 1234)
.with_original_size(5678)
.with_profile("code:api")
.with_timestamp(1703001234567)
.with_dict_version("cml-core-v1");
assert_eq!(metadata.original_size, Some(5678));
assert_eq!(metadata.profile.as_deref(), Some("code:api"));
assert_eq!(metadata.created, Some(1703001234567));
assert_eq!(metadata.dict_version.as_deref(), Some("cml-core-v1"));
}
#[test]
fn test_metadata_json_roundtrip() {
let metadata = CardMetadata::new("test::doc", 1234)
.with_original_size(5678)
.with_profile("code:api")
.with_timestamp(1703001234567);
let json = metadata.to_json().unwrap();
let loaded = CardMetadata::from_json(&json).unwrap();
assert_eq!(loaded, metadata);
}
#[test]
fn test_metadata_optional_fields() {
let metadata = CardMetadata::new("minimal", 100);
let json = metadata.to_json().unwrap();
let json_str = String::from_utf8(json).unwrap();
assert!(!json_str.contains("original_size"));
assert!(!json_str.contains("profile"));
assert!(!json_str.contains("created"));
assert!(!json_str.contains("dict_version"));
}
}