tokio-dbus 0.1.0

Pure Rust D-Bus implementation for Tokio.
Documentation
use crate::error::Result;
use crate::{Frame, Signature, Storable};

pub(crate) mod sealed {
    pub trait Sealed {}
}

/// Trait for types which can be written to.
pub trait WriteAligned {
    /// Only write to the buffer without appending a signature.
    fn write_only<T>(&mut self, value: &T)
    where
        T: ?Sized + Write;

    /// Only store the specified value without appending its signature.
    fn store<T>(&mut self, frame: T) -> Result<()>
    where
        T: Storable;

    /// Only store the specified value without appending its signature.
    fn store_frame<T>(&mut self, frame: T)
    where
        T: Frame;

    /// Extend the buffer with a slice.
    fn extend_from_slice(&mut self, bytes: &[u8]);

    /// Extend the buffer with a slice ending with a NUL byte.
    fn extend_from_slice_nul(&mut self, bytes: &[u8]);
}

/// Trait for types which can be written unaligned to.
pub trait WriteUnaligned {
    /// Only store the specified value without appending its signature.
    fn store<T>(&mut self, frame: T)
    where
        T: Frame;

    /// Extend the buffer with a slice.
    fn extend_from_slice(&mut self, bytes: &[u8]);

    /// Extend the buffer with a slice ending with a NUL byte.
    fn extend_from_slice_nul(&mut self, bytes: &[u8]);
}

/// A type who's reference can be written directly to a buffer.
///
/// These types are written using methods such as [`BodyBuf::store`].
///
/// [`BodyBuf::store`]: crate::BodyBuf::store
pub trait Write: self::sealed::Sealed {
    /// The signature of the type.
    #[doc(hidden)]
    const SIGNATURE: &'static Signature;

    /// Write `self` into `buf`.
    #[doc(hidden)]
    fn write_to<B>(&self, buf: &mut B)
    where
        B: ?Sized + WriteAligned;

    /// Write `self` into `buf`.
    #[doc(hidden)]
    fn write_to_unaligned<B>(&self, buf: &mut B)
    where
        B: ?Sized + WriteUnaligned;
}

impl self::sealed::Sealed for [u8] {}

/// Write a byte array to the buffer.
///
/// # Examples
///
/// ```
/// use tokio_dbus::BodyBuf;
///
/// let mut buf = BodyBuf::new();
/// buf.store(&b"foo"[..]);
///
/// assert_eq!(buf.signature(), "ay");
/// assert_eq!(buf.get(), &[3, 0, 0, 0, 102, 111, 111]);
/// # Ok::<_, tokio_dbus::Error>(())
/// ```
impl Write for [u8] {
    const SIGNATURE: &'static Signature = Signature::new_const(b"ay");

    #[inline]
    fn write_to<B>(&self, buf: &mut B)
    where
        B: ?Sized + WriteAligned,
    {
        buf.store_frame(self.len() as u32);
        buf.extend_from_slice(self);
    }

    #[inline]
    fn write_to_unaligned<B>(&self, buf: &mut B)
    where
        B: ?Sized + WriteUnaligned,
    {
        buf.store(self.len() as u32);
        buf.extend_from_slice(self);
    }
}

impl_traits_for_write!([u8], &b"abcd"[..], "qay");

impl self::sealed::Sealed for str {}

/// Write a length-prefixed string to the buffer.
///
/// # Examples
///
/// ```
/// use tokio_dbus::{BodyBuf, Signature};
///
/// let mut buf = BodyBuf::new();
/// buf.store("foo");
///
/// assert_eq!(buf.signature(), Signature::STRING);
/// assert_eq!(buf.get(), &[3, 0, 0, 0, 102, 111, 111, 0])
/// ```
impl Write for str {
    const SIGNATURE: &'static Signature = Signature::STRING;

    #[inline]
    fn write_to<B>(&self, buf: &mut B)
    where
        B: ?Sized + WriteAligned,
    {
        buf.store_frame(self.len() as u32);
        buf.extend_from_slice_nul(self.as_bytes());
    }

    #[inline]
    fn write_to_unaligned<B>(&self, buf: &mut B)
    where
        B: ?Sized + WriteUnaligned,
    {
        buf.store(self.len() as u32);
        buf.extend_from_slice_nul(self.as_bytes());
    }
}

impl_traits_for_write!(str, "Hello World", "qs");