LiosK / uuid7-rs

A Rust implementation of UUID version 7
Apache License 2.0
31 stars 0 forks source link

feat: use u128 for serde to avoid excess length info #3

Closed George-Miao closed 1 year ago

George-Miao commented 1 year ago

This PR uses u128 for serialization instead of bare bytes because for serializers like bincode, it will add extra 8 bytes of length info for byte sequence, which, in this case, is unnecessary.

LiosK commented 1 year ago

I'd rather prefer the binary compatibility with https://crates.io/crates/uuid in the serialized form. I'm also concerned that u128 is not natively supported by many serialization schemes.

George-Miao commented 1 year ago

I'd rather prefer the binary compatibility with https://crates.io/crates/uuid in the serialized form. I'm also concerned that u128 is not natively supported by many serialization schemes.

I see. What about an opt-in helper with #[serde(with = "module")]?

LiosK commented 1 year ago

You can do that yourself, can't you?

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
struct MyEntity {
    #[serde(with = "serde_uuid7")]
    id: uuid7::Uuid,
    value: f64,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let value = MyEntity {
        id: uuid7::uuid7(),
        value: 42.0,
    };
    println!("{:?}", value);

    let encoded = bincode::serialize(&value)?;
    println!("{:?}", encoded);

    let decoded: MyEntity = bincode::deserialize(&encoded[..])?;
    println!("{:?}", decoded);

    Ok(())
}

mod serde_uuid7 {
    use serde::{de, Deserializer, Serializer};
    use std::fmt;

    pub fn serialize<S: Serializer>(v: &uuid7::Uuid, s: S) -> Result<S::Ok, S::Error> {
        s.serialize_u128(u128::from(*v))
    }

    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<uuid7::Uuid, D::Error> {
        d.deserialize_u128(VisitorImpl)
    }

    struct VisitorImpl;

    impl<'de> de::Visitor<'de> for VisitorImpl {
        type Value = uuid7::Uuid;

        fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(formatter, "a UUID representation")
        }

        fn visit_u128<E: de::Error>(self, value: u128) -> Result<Self::Value, E> {
            Ok(Self::Value::from(value))
        }
    }
}
George-Miao commented 1 year ago

Yeah I think this will work too.