use crate::Result;
use crate::cache::models::CacheEntry;
use std::collections::HashMap;
pub trait CacheEntrySerializer {
fn serialize(
&self,
entries: &HashMap<String, Vec<CacheEntry>>,
) -> Result<String>;
fn deserialize(
&self,
text: &str,
) -> Result<HashMap<String, Vec<CacheEntry>>>;
}
pub struct JsonCacheEntrySerializer;
impl CacheEntrySerializer for JsonCacheEntrySerializer {
fn serialize(
&self,
entries: &HashMap<String, Vec<CacheEntry>>,
) -> Result<String> {
Ok(serde_json::to_string_pretty(&entries)?)
}
fn deserialize(
&self,
text: &str,
) -> Result<HashMap<String, Vec<CacheEntry>>> {
Ok(serde_json::from_str(text)?)
}
}
#[cfg(test)]
mod tests {
use crate::utils::UtcTime;
use super::*;
fn utc(s: &str) -> UtcTime {
s.parse().unwrap()
}
#[test]
fn test_json_serialize_deserialize() -> Result<()> {
let values = HashMap::from([(
"url1".into(),
vec![
CacheEntry {
text: "a".into(),
created: utc("2025-05-17T08:01:05.307751675Z"),
},
CacheEntry {
text: "b".into(),
created: utc("2025-05-18T08:01:05.307751675Z"),
},
],
)]);
let expected_serialized = r#"
{
"url1": [
{
"text": "a",
"created": "2025-05-17T08:01:05.307751675Z"
},
{
"text": "b",
"created": "2025-05-18T08:01:05.307751675Z"
}
]
}"#
.trim();
let serialized = JsonCacheEntrySerializer.serialize(&values)?;
assert_eq!(serialized, expected_serialized);
let deserialized =
JsonCacheEntrySerializer.deserialize(expected_serialized)?;
assert_eq!(deserialized, values);
Ok(())
}
}