use crate::array_default::ArrayDefault;
use crate::prelude::*;
use serde::de::Visitor;
use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
impl<P: Precision + WordType<BITS>, const BITS: usize, const N: usize> Serialize
for HyperLogLogArray<P, BITS, N>
{
#[inline(always)]
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut seq = serializer.serialize_seq(Some(N))?;
let counters: &[HyperLogLog<P, BITS>; N] = self.as_ref();
for counter in counters {
seq.serialize_element(&counter)?;
}
seq.end()
}
}
impl<'de, P: Precision + WordType<BITS>, const BITS: usize, const N: usize> Deserialize<'de>
for HyperLogLogArray<P, BITS, N>
{
#[inline(always)]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Ok(Self::from(
deserializer.deserialize_seq(HLLArrayVisitor::default())?,
))
}
}
pub struct HLLArrayVisitor<P: Precision + WordType<BITS>, const BITS: usize, const N: usize> {
_precision: core::marker::PhantomData<P>,
}
impl<P: Precision + WordType<BITS>, const BITS: usize, const N: usize> HLLArrayVisitor<P, BITS, N> {
pub fn new() -> Self {
Self {
_precision: core::marker::PhantomData,
}
}
}
impl<P: Precision + WordType<BITS>, const BITS: usize, const N: usize> Default
for HLLArrayVisitor<P, BITS, N>
{
fn default() -> Self {
Self::new()
}
}
impl<'de, P: Precision + WordType<BITS>, const BITS: usize, const N: usize> Visitor<'de>
for HLLArrayVisitor<P, BITS, N>
{
type Value = [HyperLogLog<P, BITS>; N];
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter.write_str("an array of HLL")
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut hll_array = [HyperLogLog::default(); N];
let mut hll_array_iter = hll_array.iter_mut();
while let Some(value) = seq.next_element()? {
if let Some(target) = hll_array_iter.next() {
*target = value;
} else {
return Err(serde::de::Error::invalid_length(hll_array.len(), &self));
}
}
Ok(hll_array)
}
}
impl<P: Precision + WordType<BITS>, const BITS: usize> Serialize for HyperLogLog<P, BITS> {
#[inline(always)]
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut seq = serializer.serialize_seq(Some(self.words.len()))?;
for word in self.words.iter_elements() {
seq.serialize_element(word)?;
}
seq.end()
}
}
impl<'de, P: Precision + WordType<BITS>, const BITS: usize> Deserialize<'de>
for HyperLogLog<P, BITS>
{
#[inline(always)]
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let words: P::Words = deserializer.deserialize_seq(WordsVisitor::<P, BITS>::default())?;
Ok(Self::from_words(&words))
}
}
#[derive(Default)]
pub struct WordsVisitor<P: Precision + WordType<BITS>, const BITS: usize> {
_precision: core::marker::PhantomData<P>,
}
impl<'de, P: Precision + WordType<BITS>, const BITS: usize> Visitor<'de> for WordsVisitor<P, BITS> {
type Value = P::Words;
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter.write_str("a tuple with an array of u32 and a u32 scalar")
}
fn visit_seq<A: serde::de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut words_array = P::Words::default_array();
let number_of_elements = words_array.len();
{
let mut words_array_iter = words_array.iter_elements_mut();
while let Some(value) = seq.next_element()? {
if let Some(target) = words_array_iter.next() {
*target = value;
} else {
return Err(serde::de::Error::invalid_length(number_of_elements, &self));
}
}
}
Ok(words_array)
}
}