Skip to content
Snippets Groups Projects
  • Sean McArthur's avatar
    025d5334
    Remove ByteOrder generic methods from Buf and BufMut (#187) · 025d5334
    Sean McArthur authored
    * make Buf and BufMut usable as trait objects
    
    - All the `get_*` and `put_*` methods that take `T: ByteOrder` have
      a `where Self: Sized` bound added, so that they are only usable from
      sized types. It was impossible to make `Buf` or `BufMut` into trait
      objects before, so this change doesn't break anyone.
    - Add `get_n_be`/`get_n_le`/`put_n_be`/`put_n_le` methods that can be
      used on trait objects.
    - Deprecate the export of `ByteOrder` and methods generic on it.
    
    * remove deprecated ByteOrder methods
    
    Removes the `_be` suffix from all methods, implying that the default
    people should use is network endian.
    025d5334
    History
    Remove ByteOrder generic methods from Buf and BufMut (#187)
    Sean McArthur authored
    * make Buf and BufMut usable as trait objects
    
    - All the `get_*` and `put_*` methods that take `T: ByteOrder` have
      a `where Self: Sized` bound added, so that they are only usable from
      sized types. It was impossible to make `Buf` or `BufMut` into trait
      objects before, so this change doesn't break anyone.
    - Add `get_n_be`/`get_n_le`/`put_n_be`/`put_n_le` methods that can be
      used on trait objects.
    - Deprecate the export of `ByteOrder` and methods generic on it.
    
    * remove deprecated ByteOrder methods
    
    Removes the `_be` suffix from all methods, implying that the default
    people should use is network endian.
into_buf.rs 2.76 KiB
use super::{Buf};

use std::io;

/// Conversion into a `Buf`
///
/// An `IntoBuf` implementation defines how to convert a value into a `Buf`.
/// This is common for types that represent byte storage of some kind. `IntoBuf`
/// may be implemented directly for types or on references for those types.
///
/// # Examples
///
/// ```
/// use bytes::{Buf, IntoBuf};
///
/// let bytes = b"\x00\x01hello world";
/// let mut buf = bytes.into_buf();
///
/// assert_eq!(1, buf.get_u16());
///
/// let mut rest = [0; 11];
/// buf.copy_to_slice(&mut rest);
///
/// assert_eq!(b"hello world", &rest);
/// ```
pub trait IntoBuf {
    /// The `Buf` type that `self` is being converted into
    type Buf: Buf;

    /// Creates a `Buf` from a value.
    ///
    /// # Examples
    ///
    /// ```
    /// use bytes::{Buf, IntoBuf};
    ///
    /// let bytes = b"\x00\x01hello world";
    /// let mut buf = bytes.into_buf();
    ///
    /// assert_eq!(1, buf.get_u16());
    ///
    /// let mut rest = [0; 11];
    /// buf.copy_to_slice(&mut rest);
    ///
    /// assert_eq!(b"hello world", &rest);
    /// ```
    fn into_buf(self) -> Self::Buf;
}

impl<T: Buf> IntoBuf for T {
    type Buf = Self;

    fn into_buf(self) -> Self {
        self
    }
}

impl<'a> IntoBuf for &'a [u8] {
    type Buf = io::Cursor<&'a [u8]>;

    fn into_buf(self) -> Self::Buf {
        io::Cursor::new(self)
    }
}

impl<'a> IntoBuf for &'a str {
    type Buf = io::Cursor<&'a [u8]>;

    fn into_buf(self) -> Self::Buf {
        self.as_bytes().into_buf()
    }
}

impl IntoBuf for Vec<u8> {
    type Buf = io::Cursor<Vec<u8>>;

    fn into_buf(self) -> Self::Buf {
        io::Cursor::new(self)
    }
}

impl<'a> IntoBuf for &'a Vec<u8> {
    type Buf = io::Cursor<&'a [u8]>;

    fn into_buf(self) -> Self::Buf {
        io::Cursor::new(&self[..])
    }
}

// Kind of annoying... but this impl is required to allow passing `&'static
// [u8]` where for<'a> &'a T: IntoBuf is required.
impl<'a> IntoBuf for &'a &'static [u8] {
    type Buf = io::Cursor<&'static [u8]>;

    fn into_buf(self) -> Self::Buf {
        io::Cursor::new(self)
    }
}

impl<'a> IntoBuf for &'a &'static str {
    type Buf = io::Cursor<&'static [u8]>;

    fn into_buf(self) -> Self::Buf {
        self.as_bytes().into_buf()
    }
}

impl IntoBuf for String {
    type Buf = io::Cursor<Vec<u8>>;

    fn into_buf(self) -> Self::Buf {
        self.into_bytes().into_buf()
    }
}

impl<'a> IntoBuf for &'a String {
    type Buf = io::Cursor<&'a [u8]>;

    fn into_buf(self) -> Self::Buf {
        self.as_bytes().into_buf()
    }
}

impl IntoBuf for u8 {
    type Buf = Option<[u8; 1]>;

    fn into_buf(self) -> Self::Buf {
        Some([self])
    }
}

impl IntoBuf for i8 {
    type Buf = Option<[u8; 1]>;

    fn into_buf(self) -> Self::Buf {
        Some([self as u8; 1])
    }
}