use std::hash::{Hash, Hasher};
use std::ops::Deref;
use serde::de::Error;
use serde::ser::SerializeTuple;
use serde::{Deserialize, Serialize};
use crate::estimator::CardinalityEstimator;
use crate::representation::Representation;
impl<T, H, const P: usize, const W: usize> Serialize for CardinalityEstimator<T, H, P, W>
where
T: Hash + ?Sized,
H: Hasher + Default,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut tup = serializer.serialize_tuple(2)?;
tup.serialize_element(&self.data)?;
match self.representation() {
Representation::Small(_) => {
tup.serialize_element(&None::<Vec<u32>>)?;
}
Representation::Array(arr) => {
tup.serialize_element(&Some(arr.deref()))?;
}
Representation::Hll(hll) => {
tup.serialize_element(&Some(hll.data))?;
}
}
tup.end()
}
}
impl<'de, T, H, const P: usize, const W: usize> Deserialize<'de>
for CardinalityEstimator<T, H, P, W>
where
T: Hash + ?Sized,
H: Hasher + Default,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let (data, opt_vec): (usize, Option<Vec<u32>>) = Deserialize::deserialize(deserializer)?;
Representation::try_from(data, opt_vec).map_err(|e| Error::custom(format!("{:?}", e)))
}
}
#[cfg(test)]
pub mod tests {
use super::*;
use test_case::test_case;
#[test_case(0; "empty set")]
#[test_case(1; "single element")]
#[test_case(2; "two distinct elements")]
#[test_case(100; "hundred distinct elements")]
#[test_case(10000; "ten thousand distinct elements")]
fn test_serde(n: usize) {
let mut original_estimator = CardinalityEstimator::<str>::new();
for i in 0..n {
let item = &format!("item{}", i);
original_estimator.insert(&item);
}
let serialized = serde_json::to_string(&original_estimator).expect("serialization failed");
assert!(
!serialized.is_empty(),
"serialized string should not be empty"
);
let deserialized_estimator: CardinalityEstimator<str> =
serde_json::from_str(&serialized).expect("deserialization failed");
assert_eq!(
original_estimator.representation(),
deserialized_estimator.representation()
);
}
#[test]
fn test_deserialize_invalid_json() {
let invalid_json = "{ invalid_json_string }";
let result: Result<CardinalityEstimator<str>, _> = serde_json::from_str(invalid_json);
assert!(
result.is_err(),
"Deserialization should fail for invalid JSON"
);
}
#[test_case("[12345,null]".as_bytes(); "case 1")]
#[test_case(&[91, 49, 55, 44, 13, 10, 91, 13, 93, 93]; "case 2")]
#[test_case(&[91, 51, 44, 10, 110, 117, 108, 108, 93, 122]; "case 3")]
#[test_case(&[91, 51, 44, 10, 110, 117, 108, 108, 93]; "case 4")]
fn test_failed_deserialization(input: &[u8]) {
let result: Result<CardinalityEstimator<str>, _> = serde_json::from_slice(input);
assert!(result.is_err());
}
}