xuko 0.10.0

Rust utility library
Documentation
//! Reference counted bytes structure

use core::ops::Deref;
use std::sync::Arc;

/// Reference counted bytes structure
///
/// It is simply just a wrapper around [`Arc`]<[`u8`]>
///
/// # Examples
///
/// ```
/// use xuko::bytes::Bytes;
///
/// let bytes = Bytes::from("hello".as_bytes());
/// let clone = bytes.clone(); // Cheap clone
///
/// assert_eq!(*bytes, *clone);
/// ```
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Bytes {
    bytes: Arc<[u8]>,
}

impl Bytes {
    /// Create a new [`Bytes`].
    pub fn new(bytes: &[u8]) -> Self {
        Self {
            bytes: Arc::from(bytes),
        }
    }
}

impl<B: AsRef<[u8]>> From<B> for Bytes {
    fn from(value: B) -> Bytes {
        Bytes::new(value.as_ref())
    }
}

impl Deref for Bytes {
    type Target = [u8];

    fn deref(&self) -> &Self::Target {
        &self.bytes
    }
}

#[cfg(feature = "serde")]
impl serde::Serialize for Bytes {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        self.bytes.serialize(serializer)
    }
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Bytes {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let bytes = Vec::deserialize(deserializer)?;
        Ok(Self::from(bytes))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn bytes() {
        let b = Bytes::from([1, 2, 3]);
        let rc = b.clone();

        assert_eq!(b.first(), Some(&1));
        assert_eq!(*b, *rc);

        let _ = Bytes::clone(&b);
    }
}