1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::{collections::HashSet, fmt::Display, hash::Hash, num::TryFromIntError};

use cosmian_crypto_core::{
    bytes_ser_de::{Deserializer, Serializable, Serializer},
    CryptoCoreError,
};
use cosmian_findex::{parameters::UID_LENGTH, CoreError as FindexCoreError, Uid};

#[derive(Debug)]
pub enum SerializableSetError {
    Serialization(String),
    Conversion(TryFromIntError),
}

impl Display for SerializableSetError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Serialization(error) => write!(f, "{error}"),
            Self::Conversion(error) => write!(f, "{error}"),
        }
    }
}

impl std::error::Error for SerializableSetError {}

impl From<CryptoCoreError> for SerializableSetError {
    fn from(value: CryptoCoreError) -> Self {
        Self::Serialization(value.to_string())
    }
}

impl From<FindexCoreError> for SerializableSetError {
    fn from(value: FindexCoreError) -> Self {
        Self::Serialization(value.to_string())
    }
}

impl From<TryFromIntError> for SerializableSetError {
    fn from(value: TryFromIntError) -> Self {
        Self::Conversion(value)
    }
}

pub fn serialize_set<SerializationError, T>(
    set: &HashSet<T>,
) -> Result<Vec<u8>, SerializableSetError>
where
    T: Serializable<Error = SerializationError> + Hash,
    SerializableSetError: From<SerializationError>,
{
    let mut ser = Serializer::with_capacity(set.len());
    ser.write_leb128_u64(set.len() as u64)?;
    for element in set {
        ser.write(element)?;
    }
    Ok(ser.finalize().to_vec())
}

pub fn deserialize_set<SerializationError, T>(
    bytes: &[u8],
) -> Result<HashSet<T>, SerializableSetError>
where
    T: Serializable<Error = SerializationError> + Eq + Hash,
    SerializableSetError: From<SerializationError>,
{
    let mut de = Deserializer::new(bytes);
    let length = usize::try_from(de.read_leb128_u64()?)?;
    let mut set = HashSet::with_capacity(length);
    for _ in 0..length {
        set.insert(de.read::<T>()?);
    }
    if de.value().is_empty() {
        Ok(set)
    } else {
        Err(SerializableSetError::Serialization(
            "Remaining bytes after set deserialization".to_string(),
        ))
    }
}

pub fn deserialize_fetch_entry_table_results(
    bytes: &[u8],
) -> Result<Vec<(Uid<UID_LENGTH>, Vec<u8>)>, SerializableSetError> {
    let mut de = Deserializer::new(bytes);
    let length = <usize>::try_from(de.read_leb128_u64()?)?;
    let mut items = Vec::with_capacity(length);
    for _ in 0..length {
        let key = Uid::from(de.read_array()?);
        let value = de.read_vec()?;
        items.push((key, value));
    }
    Ok(items)
}