bytes icon indicating copy to clipboard operation
bytes copied to clipboard

Support for Arc

Open yossyX opened this issue 2 years ago • 4 comments

serde supports Arc with the 'rc' feature. Is it possible to have support for Arc<Vec< u8>>?

yossyX avatar Nov 04 '23 01:11 yossyX

In the meantime, the following code can be used to address this issue.

struct Data {
    #[serde(with = "arc_bytes")]
    pub val: std::sync::Arc<Vec<u8>>,
    #[serde(with = "option_arc_bytes")]
    pub val2: Option<std::sync::Arc<Vec<u8>>>,
}
mod arc_bytes {
    use serde::{Deserialize, Deserializer, Serializer};
    use serde_bytes::ByteBuf;
    use std::sync::Arc;

    pub fn serialize<S>(data: &Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_bytes(data.as_slice())
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Arc<Vec<u8>>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let buf = ByteBuf::deserialize(deserializer)?;
        Ok(Arc::new(buf.into_vec()))
    }
}
mod option_arc_bytes {
    use serde::{Deserialize, Deserializer, Serializer};
    use serde_bytes::ByteBuf;
    use std::sync::Arc;

    pub fn serialize<S>(data: &Option<Arc<Vec<u8>>>, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        match data {
            Some(value) => serializer.serialize_bytes(value.as_slice()),
            None => serializer.serialize_none(),
        }
    }

    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Arc<Vec<u8>>>, D::Error>
    where
        D: Deserializer<'de>,
    {
        match Option::<ByteBuf>::deserialize(deserializer)? {
            Some(buf) => Ok(Some(Arc::new(buf.into_vec()))),
            None => Ok(None),
        }
    }
}

yossyX avatar Nov 05 '23 01:11 yossyX

Just putting in another request here for this -- have also worked around it myself.

tekacs avatar Mar 06 '24 03:03 tekacs

Also Arc<[u8]> ~and Box<[u8]>~. :pray: (Edit: Looks like Box already works.)

(Not sure about Arc<Vec<u8>>: That Vec can't be modified anyway once the Arc is shared, so you might as well drop the "capacity" bytes and use Arc<[u8]>.)

afck avatar Dec 19 '24 10:12 afck

Instead of serde_bytes you can also use serde_with::Bytes for the same. You can combine it with Arc or Option however needed.

use serde_with::*;

#[serde_as]
#[derive(Deserialize, Serialize)]
struct Data {
    #[serde_as(as = "Arc<Bytes>")]
    array: Arc<[u8; 15]>,
    #[serde_as(as = "Arc<Bytes>")]
    boxed: Arc<Box<[u8]>>,
    #[serde_as(as = "Option<Arc<Bytes>>")]
    option: Option<Arc<Vec<u8>>>,
}

jonasbb avatar Dec 25 '24 21:12 jonasbb