Skip to content

Commit

Permalink
alloc support (for no_std environments)
Browse files Browse the repository at this point in the history
Gates all allocator-dependent features on the 'alloc' cargo feature,
allowing use in no_std environments which have a heap and defined
allocator, but not full support for 'std'.
  • Loading branch information
tarcieri committed Apr 14, 2019
1 parent 18f2a7e commit 9c3a781
Show file tree
Hide file tree
Showing 19 changed files with 112 additions and 28 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Expand Up @@ -37,6 +37,10 @@ matrix:
- env: EXTRA_ARGS="--no-default-features"
script: cargo build $EXTRA_ARGS

# `alloc` crate-based implementation
- env: EXTRA_ARGS="--no-default-features --features=alloc --lib --tests"
rust: nightly # TODO: test 'alloc' on stable rust when it is fully stabilized

# Serde implementation
- env: EXTRA_ARGS="--features serde"

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Expand Up @@ -38,5 +38,6 @@ serde_test = "1.0"

[features]
default = ["std"]
alloc = []
i128 = ["byteorder/i128"]
std = ["iovec"]
std = ["alloc", "iovec"]
4 changes: 2 additions & 2 deletions src/buf/buf.rs
Expand Up @@ -2,7 +2,7 @@ use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
use byteorder::{BigEndian, ByteOrder, LittleEndian};
#[cfg(feature = "iovec")]
use iovec::IoVec;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use prelude::*;

use core::{cmp, ptr};
Expand Down Expand Up @@ -1077,7 +1077,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<T: Buf + ?Sized> Buf for Box<T> {
fn remaining(&self) -> usize {
(**self).remaining()
Expand Down
7 changes: 4 additions & 3 deletions src/buf/buf_mut.rs
Expand Up @@ -2,7 +2,7 @@ use super::{IntoBuf, Writer};
use byteorder::{LittleEndian, ByteOrder, BigEndian};
#[cfg(feature = "iovec")]
use iovec::IoVec;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use prelude::*;

use core::{cmp, ptr, usize};
Expand Down Expand Up @@ -1088,7 +1088,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl<T: BufMut + ?Sized> BufMut for Box<T> {
fn remaining_mut(&self) -> usize {
(**self).remaining_mut()
Expand All @@ -1098,6 +1098,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
(**self).bytes_mut()
}

#[cfg(feature = "iovec")]
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
(**self).bytes_vec_mut(dst)
}
Expand Down Expand Up @@ -1136,7 +1137,7 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl BufMut for Vec<u8> {
#[inline]
fn remaining_mut(&self) -> usize {
Expand Down
10 changes: 5 additions & 5 deletions src/buf/from_buf.rs
@@ -1,7 +1,7 @@
use {IntoBuf};
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use prelude::*;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
use {Buf, BufMut, Bytes, BytesMut};

/// Conversion from a [`Buf`]
Expand Down Expand Up @@ -90,7 +90,7 @@ pub trait FromBuf {
fn from_buf<T>(buf: T) -> Self where T: IntoBuf;
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl FromBuf for Vec<u8> {
fn from_buf<T>(buf: T) -> Self
where T: IntoBuf
Expand All @@ -102,7 +102,7 @@ impl FromBuf for Vec<u8> {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl FromBuf for Bytes {
fn from_buf<T>(buf: T) -> Self
where T: IntoBuf
Expand All @@ -111,7 +111,7 @@ impl FromBuf for Bytes {
}
}

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
impl FromBuf for BytesMut {
fn from_buf<T>(buf: T) -> Self
where T: IntoBuf
Expand Down
2 changes: 1 addition & 1 deletion src/buf/mod.rs
Expand Up @@ -24,7 +24,7 @@ mod into_buf;
mod iter;
mod reader;
mod take;
#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
mod vec_deque;
mod writer;

Expand Down
3 changes: 3 additions & 0 deletions src/buf/vec_deque.rs
@@ -1,3 +1,6 @@
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::collections::vec_deque::VecDeque;
#[cfg(feature = "std")]
use std::collections::VecDeque;

use super::Buf;
Expand Down
25 changes: 19 additions & 6 deletions src/bytes.rs
@@ -1,14 +1,19 @@
use {IntoBuf, Buf, BufMut};
use {BufMut};
#[cfg(feature = "std")]
use {Buf, IntoBuf};
#[cfg(feature = "std")]
use buf::Iter;
use debug;
use prelude::*;

use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize};
use std::borrow::{Borrow, BorrowMut};
use core::{cmp, fmt, mem, hash, ops, slice, ptr, usize};
use core::borrow::{Borrow, BorrowMut};
use core::sync::atomic::{self, AtomicUsize, AtomicPtr};
use core::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
use core::iter::{FromIterator, Iterator};

#[cfg(feature = "std")]
use std::io::Cursor;
use std::sync::atomic::{self, AtomicUsize, AtomicPtr};
use std::sync::atomic::Ordering::{Relaxed, Acquire, Release, AcqRel};
use std::iter::{FromIterator, Iterator};

/// A reference counted contiguous slice of memory.
///
Expand Down Expand Up @@ -835,6 +840,7 @@ impl Bytes {
}
}

#[cfg(feature = "std")]
impl IntoBuf for Bytes {
type Buf = Cursor<Self>;

Expand All @@ -843,6 +849,7 @@ impl IntoBuf for Bytes {
}
}

#[cfg(feature = "std")]
impl<'a> IntoBuf for &'a Bytes {
type Buf = Cursor<Self>;

Expand Down Expand Up @@ -986,6 +993,7 @@ impl Borrow<[u8]> for Bytes {
}
}

#[cfg(feature = "std")]
impl IntoIterator for Bytes {
type Item = u8;
type IntoIter = Iter<Cursor<Bytes>>;
Expand All @@ -995,6 +1003,7 @@ impl IntoIterator for Bytes {
}
}

#[cfg(feature = "std")]
impl<'a> IntoIterator for &'a Bytes {
type Item = u8;
type IntoIter = Iter<Cursor<&'a Bytes>>;
Expand Down Expand Up @@ -1563,6 +1572,7 @@ impl BufMut for BytesMut {
}
}

#[cfg(feature = "std")]
impl IntoBuf for BytesMut {
type Buf = Cursor<Self>;

Expand All @@ -1571,6 +1581,7 @@ impl IntoBuf for BytesMut {
}
}

#[cfg(feature = "std")]
impl<'a> IntoBuf for &'a BytesMut {
type Buf = Cursor<&'a BytesMut>;

Expand Down Expand Up @@ -1736,6 +1747,7 @@ impl Clone for BytesMut {
}
}

#[cfg(feature = "std")]
impl IntoIterator for BytesMut {
type Item = u8;
type IntoIter = Iter<Cursor<BytesMut>>;
Expand All @@ -1745,6 +1757,7 @@ impl IntoIterator for BytesMut {
}
}

#[cfg(feature = "std")]
impl<'a> IntoIterator for &'a BytesMut {
type Item = u8;
type IntoIter = Iter<Cursor<&'a BytesMut>>;
Expand Down
2 changes: 1 addition & 1 deletion src/debug.rs
@@ -1,4 +1,4 @@
use std::fmt;
use core::fmt;

/// Alternative implementation of `fmt::Debug` for byte slice.
///
Expand Down
10 changes: 6 additions & 4 deletions src/lib.rs
Expand Up @@ -71,7 +71,10 @@
#![deny(warnings, missing_docs, missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/bytes/0.4.12")]
#![no_std]
#![cfg_attr(feature = "alloc", feature(alloc))]

#[cfg(feature = "alloc")]
extern crate alloc;
extern crate byteorder;
#[cfg(feature = "iovec")]
extern crate iovec;
Expand All @@ -92,13 +95,12 @@ pub use buf::{
Take,
};

#[cfg(feature = "std")]
#[cfg(feature = "alloc")]
mod bytes;
#[cfg(feature = "std")]
mod debug;
#[cfg(feature = "std")]
pub use bytes::{Bytes, BytesMut};
mod prelude;
#[cfg(feature = "alloc")]
pub use bytes::{Bytes, BytesMut};

#[deprecated]
pub use byteorder::{ByteOrder, BigEndian, LittleEndian};
Expand Down
10 changes: 10 additions & 0 deletions src/prelude.rs
@@ -1,5 +1,15 @@
//! Crate-local import prelude, primarily intended as a facade for accessing
//! heap-allocated data structures.

#[cfg(all(feature = "alloc", not(feature = "std")))]
mod alloc_prelude {
pub use alloc::boxed::Box;
pub use alloc::string::String;
pub use alloc::vec::Vec;
}

#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use self::alloc_prelude::*;

#[cfg(feature = "std")]
pub use std::prelude::v1::*;
9 changes: 9 additions & 0 deletions tests/test_buf.rs
@@ -1,12 +1,17 @@
extern crate bytes;
extern crate byteorder;
#[cfg(feature = "iovec")]
extern crate iovec;

#[cfg(feature = "std")]
use bytes::Buf;
#[cfg(feature = "iovec")]
use iovec::IoVec;
#[cfg(feature = "std")]
use std::io::Cursor;

#[test]
#[cfg(feature = "std")]
fn test_fresh_cursor_vec() {
let mut buf = Cursor::new(b"hello".to_vec());

Expand All @@ -25,12 +30,14 @@ fn test_fresh_cursor_vec() {
}

#[test]
#[cfg(feature = "std")]
fn test_get_u8() {
let mut buf = Cursor::new(b"\x21zomg");
assert_eq!(0x21, buf.get_u8());
}

#[test]
#[cfg(feature = "std")]
fn test_get_u16() {
let buf = b"\x21\x54zomg";
assert_eq!(0x2154, Cursor::new(buf).get_u16_be());
Expand All @@ -39,12 +46,14 @@ fn test_get_u16() {

#[test]
#[should_panic]
#[cfg(feature = "std")]
fn test_get_u16_buffer_underflow() {
let mut buf = Cursor::new(b"\x21");
buf.get_u16_be();
}

#[test]
#[cfg(all(feature = "iovec", feature = "std"))]
fn test_bufs_vec() {
let buf = Cursor::new(b"hello world");

Expand Down
11 changes: 10 additions & 1 deletion tests/test_buf_mut.rs
@@ -1,13 +1,20 @@
extern crate bytes;
extern crate byteorder;
#[cfg(feature = "iovec")]
extern crate iovec;

use bytes::{BufMut, BytesMut};
use bytes::BufMut;
#[cfg(feature = "std")]
use bytes::BytesMut;
#[cfg(feature = "iovec")]
use iovec::IoVec;
#[cfg(feature = "std")]
use std::usize;
#[cfg(feature = "std")]
use std::fmt::Write;

#[test]
#[cfg(feature = "std")]
fn test_vec_as_mut_buf() {
let mut buf = Vec::with_capacity(64);

Expand Down Expand Up @@ -61,6 +68,7 @@ fn test_vec_advance_mut() {
}

#[test]
#[cfg(feature = "std")]
fn test_clone() {
let mut buf = BytesMut::with_capacity(100);
buf.write_str("this is a test").unwrap();
Expand All @@ -71,6 +79,7 @@ fn test_clone() {
}

#[test]
#[cfg(feature = "iovec")]
fn test_bufs_vec_mut() {
use std::mem;

Expand Down

0 comments on commit 9c3a781

Please sign in to comment.