serde-rs / bytes

Wrapper types to enable optimized handling of &[u8] and Vec<u8>
Apache License 2.0
306 stars 37 forks source link

Implement (de-)serializing for `[u8; N]` #26

Closed KizzyCode closed 8 months ago

KizzyCode commented 3 years ago

Now that const_generics are stable, I wonder if it is possible to implement support for [u8; N] arrays (serde seems to support them)?

PiDelport commented 3 years ago

Here's a stop-gap implementation that can be dropped into existing projects:

mod serde_bytes_array {
    use core::convert::TryInto;

    use serde::de::Error;
    use serde::{Deserializer, Serializer};

    /// This just specializes [`serde_bytes::serialize`] to `<T = [u8]>`.
    pub(crate) fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serde_bytes::serialize(bytes, serializer)
    }

    /// This takes the result of [`serde_bytes::deserialize`] from `[u8]` to `[u8; N]`.
    pub(crate) fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<[u8; N], D::Error>
    where
        D: Deserializer<'de>,
    {
        let slice: &[u8] = serde_bytes::deserialize(deserializer)?;
        let array: [u8; N] = slice.try_into().map_err(|_| {
            let expected = format!("[u8; {}]", N);
            D::Error::invalid_length(slice.len(), &expected.as_str())
        })?;
        Ok(array)
    }
}

and used with:

#[serde(with = "serde_bytes_array")]
so-schen commented 9 months ago

I created another crate based on latest version of serde_bytes and add generic byte array support. @dtolnay can be merged into this? https://crates.io/crates/serde_bytes_ng