Blomex
Blomex

Reputation: 427

Rust deserialization: converting vector of bytes to hashset of uuid

My goal is to serialize (HashSet<Uuid> -> Vec<u8>) and deserialize (&[u8] -> HashSet<Uuid>) hashset of uuids.

I have following serialization:

fn serialize(set: HashSet<Uuid>) -> Vec<u8>{
  set.into_iter().map(|x| x.as_bytes()).collect()
}

My tries on writing on deserialization ended up on something like this, when I knew exact number of uuids:

fn clone_into_array<A, T>(slice: &[T]) -> A
            where A: Sized + Default + std::convert::AsMut<[T]>,
                  T: Clone
        {
            let mut a = Default::default();
            <A as std::convert::AsMut<[T]>>::as_mut(&mut a).clone_from_slice(slice);
            a
        }
fn deserialize(data: &[u8]){
    let first_uuid = Uuid::from_bytes(clone_into_array(&data[0..16]))
    ...

}

Questions: Is my serialization even correct?

How can I deserialize from &[u8] back to HashSet<Uuid> if I know it was previously serialized using serialize function if I don't know exact set size?

Is my approach to deserialization correct or there is other, much cleaner approach?

Upvotes: 0

Views: 1248

Answers (1)

Aplet123
Aplet123

Reputation: 35540

Your serialization is incorrect, as it tries to collect a Vec<u8> from a Iterator<Item = &[u8; 16]>. You can instead fold the iterator and extend a Vec over the slices. For deserialization, you know each Uuid will take up 16 bytes, so you should use chunks_exact to iterate over that and collect into a hashset:

fn serialize(set: HashSet<Uuid>) -> Vec<u8>{
    set.into_iter().fold(Vec::new(), |mut acc, v| {
        acc.extend_from_slice(v.as_bytes());
        acc
    })
}

fn deserialize(bytes: &[u8]) -> HashSet<Uuid> {
    bytes.chunks_exact(16).map(Uuid::from_slice).collect::<Result<_, _>>().unwrap()
}

Playground link

Upvotes: 2

Related Questions