From 18f2a7e05a6e97e09215a9a59e63eb5cb7f40ea6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Apr 2019 07:53:39 -0700 Subject: [PATCH 1/2] no_std support (with default-enabled "std" cargo feature) Feature gates anything dependent on `std` on the eponymous cargo feature, and changes references to libcore features from `std` to `core` --- .travis.yml | 4 ++++ Cargo.toml | 6 ++++-- src/buf/buf.rs | 12 +++++++++++- src/buf/buf_mut.rs | 14 ++++++++++++-- src/buf/chain.rs | 3 +++ src/buf/from_buf.rs | 9 ++++++++- src/buf/into_buf.rs | 12 ++++++++++++ src/buf/mod.rs | 1 + src/buf/reader.rs | 3 +++ src/buf/take.rs | 2 +- src/buf/vec_deque.rs | 1 + src/buf/writer.rs | 2 ++ src/bytes.rs | 3 ++- src/lib.rs | 8 ++++++++ src/prelude.rs | 5 +++++ src/serde.rs | 3 ++- 16 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 src/prelude.rs diff --git a/.travis.yml b/.travis.yml index 2e8ab181c..e332ce1f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,10 @@ matrix: - env: RUST_TEST_THREADS=1 TARGET=powerpc-unknown-linux-gnu - env: RUST_TEST_THREADS=1 TARGET=powerpc64-unknown-linux-gnu + # Ensure crate compiles without default features (i.e. for no_std) + - env: EXTRA_ARGS="--no-default-features" + script: cargo build $EXTRA_ARGS + # Serde implementation - env: EXTRA_ARGS="--features serde" diff --git a/Cargo.toml b/Cargo.toml index 99331b69a..3dc10d857 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,14 +22,14 @@ exclude = [ "bench/**/*", "test/**/*" ] -categories = ["network-programming", "data-structures"] +categories = ["network-programming", "data-structures", "no-std"] [package.metadata.docs.rs] features = ["i128"] [dependencies] byteorder = "1.1.0" -iovec = "0.1" +iovec = { version = "0.1", optional = true } serde = { version = "1.0", optional = true } either = { version = "1.5", default-features = false, optional = true } @@ -37,4 +37,6 @@ either = { version = "1.5", default-features = false, optional = true } serde_test = "1.0" [features] +default = ["std"] i128 = ["byteorder/i128"] +std = ["iovec"] diff --git a/src/buf/buf.rs b/src/buf/buf.rs index dc20567d3..06738d668 100644 --- a/src/buf/buf.rs +++ b/src/buf/buf.rs @@ -1,8 +1,13 @@ use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain}; use byteorder::{BigEndian, ByteOrder, LittleEndian}; +#[cfg(feature = "iovec")] use iovec::IoVec; +#[cfg(feature = "std")] +use prelude::*; -use std::{cmp, io, ptr}; +use core::{cmp, ptr}; +#[cfg(feature = "std")] +use std::io; macro_rules! buf_get_impl { ($this:ident, $size:expr, $conv:path) => ({ @@ -146,6 +151,7 @@ pub trait Buf { /// with `dst` being a zero length slice. /// /// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + #[cfg(feature = "iovec")] fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize { if dst.is_empty() { return 0; @@ -1061,6 +1067,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T { (**self).bytes() } + #[cfg(feature = "iovec")] fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize { (**self).bytes_vec(dst) } @@ -1070,6 +1077,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T { } } +#[cfg(feature = "std")] impl Buf for Box { fn remaining(&self) -> usize { (**self).remaining() @@ -1079,6 +1087,7 @@ impl Buf for Box { (**self).bytes() } + #[cfg(feature = "iovec")] fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize { (**self).bytes_vec(dst) } @@ -1088,6 +1097,7 @@ impl Buf for Box { } } +#[cfg(feature = "std")] impl> Buf for io::Cursor { fn remaining(&self) -> usize { let len = self.get_ref().as_ref().len(); diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs index 7f3c1f756..265b66668 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1,8 +1,13 @@ use super::{IntoBuf, Writer}; use byteorder::{LittleEndian, ByteOrder, BigEndian}; +#[cfg(feature = "iovec")] use iovec::IoVec; +#[cfg(feature = "std")] +use prelude::*; -use std::{cmp, io, ptr, usize}; +use core::{cmp, ptr, usize}; +#[cfg(feature = "std")] +use std::io; /// A trait for values that provide sequential write access to bytes. /// @@ -189,6 +194,7 @@ pub trait BufMut { /// with `dst` being a zero length slice. /// /// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html + #[cfg(feature = "iovec")] unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize { if dst.is_empty() { return 0; @@ -1072,6 +1078,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut 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) } @@ -1081,6 +1088,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T { } } +#[cfg(feature = "std")] impl BufMut for Box { fn remaining_mut(&self) -> usize { (**self).remaining_mut() @@ -1099,6 +1107,7 @@ impl BufMut for Box { } } +#[cfg(feature = "std")] impl + AsRef<[u8]>> BufMut for io::Cursor { fn remaining_mut(&self) -> usize { use Buf; @@ -1127,6 +1136,7 @@ impl + AsRef<[u8]>> BufMut for io::Cursor { } } +#[cfg(feature = "std")] impl BufMut for Vec { #[inline] fn remaining_mut(&self) -> usize { @@ -1148,7 +1158,7 @@ impl BufMut for Vec { #[inline] unsafe fn bytes_mut(&mut self) -> &mut [u8] { - use std::slice; + use core::slice; if self.capacity() == self.len() { self.reserve(64); // Grow the vec diff --git a/src/buf/chain.rs b/src/buf/chain.rs index 7dd44ab02..f0526a657 100644 --- a/src/buf/chain.rs +++ b/src/buf/chain.rs @@ -1,4 +1,5 @@ use {Buf, BufMut}; +#[cfg(feature = "iovec")] use iovec::IoVec; /// A `Chain` sequences two buffers. @@ -177,6 +178,7 @@ impl Buf for Chain self.b.advance(cnt); } + #[cfg(feature = "iovec")] fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize { let mut n = self.a.bytes_vec(dst); n += self.b.bytes_vec(&mut dst[n..]); @@ -218,6 +220,7 @@ impl BufMut for Chain self.b.advance_mut(cnt); } + #[cfg(feature = "iovec")] unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize { let mut n = self.a.bytes_vec_mut(dst); n += self.b.bytes_vec_mut(&mut dst[n..]); diff --git a/src/buf/from_buf.rs b/src/buf/from_buf.rs index 55f5cef31..58e8d2374 100644 --- a/src/buf/from_buf.rs +++ b/src/buf/from_buf.rs @@ -1,4 +1,8 @@ -use {Buf, BufMut, IntoBuf, Bytes, BytesMut}; +use {IntoBuf}; +#[cfg(feature = "std")] +use prelude::*; +#[cfg(feature = "std")] +use {Buf, BufMut, Bytes, BytesMut}; /// Conversion from a [`Buf`] /// @@ -86,6 +90,7 @@ pub trait FromBuf { fn from_buf(buf: T) -> Self where T: IntoBuf; } +#[cfg(feature = "std")] impl FromBuf for Vec { fn from_buf(buf: T) -> Self where T: IntoBuf @@ -97,6 +102,7 @@ impl FromBuf for Vec { } } +#[cfg(feature = "std")] impl FromBuf for Bytes { fn from_buf(buf: T) -> Self where T: IntoBuf @@ -105,6 +111,7 @@ impl FromBuf for Bytes { } } +#[cfg(feature = "std")] impl FromBuf for BytesMut { fn from_buf(buf: T) -> Self where T: IntoBuf diff --git a/src/buf/into_buf.rs b/src/buf/into_buf.rs index 4c3b42072..60a4a7ca5 100644 --- a/src/buf/into_buf.rs +++ b/src/buf/into_buf.rs @@ -1,5 +1,8 @@ use super::{Buf}; +#[cfg(feature = "std")] +use prelude::*; +#[cfg(feature = "std")] use std::io; /// Conversion into a `Buf` @@ -55,6 +58,7 @@ impl IntoBuf for T { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a [u8] { type Buf = io::Cursor<&'a [u8]>; @@ -63,6 +67,7 @@ impl<'a> IntoBuf for &'a [u8] { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a mut [u8] { type Buf = io::Cursor<&'a mut [u8]>; @@ -71,6 +76,7 @@ impl<'a> IntoBuf for &'a mut [u8] { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a str { type Buf = io::Cursor<&'a [u8]>; @@ -79,6 +85,7 @@ impl<'a> IntoBuf for &'a str { } } +#[cfg(feature = "std")] impl IntoBuf for Vec { type Buf = io::Cursor>; @@ -87,6 +94,7 @@ impl IntoBuf for Vec { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a Vec { type Buf = io::Cursor<&'a [u8]>; @@ -97,6 +105,7 @@ impl<'a> IntoBuf for &'a Vec { // Kind of annoying... but this impl is required to allow passing `&'static // [u8]` where for<'a> &'a T: IntoBuf is required. +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a &'static [u8] { type Buf = io::Cursor<&'static [u8]>; @@ -105,6 +114,7 @@ impl<'a> IntoBuf for &'a &'static [u8] { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a &'static str { type Buf = io::Cursor<&'static [u8]>; @@ -113,6 +123,7 @@ impl<'a> IntoBuf for &'a &'static str { } } +#[cfg(feature = "std")] impl IntoBuf for String { type Buf = io::Cursor>; @@ -121,6 +132,7 @@ impl IntoBuf for String { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a String { type Buf = io::Cursor<&'a [u8]>; diff --git a/src/buf/mod.rs b/src/buf/mod.rs index 35b4857ec..efa7d0b2d 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -24,6 +24,7 @@ mod into_buf; mod iter; mod reader; mod take; +#[cfg(feature = "std")] mod vec_deque; mod writer; diff --git a/src/buf/reader.rs b/src/buf/reader.rs index f1154dace..607794bbf 100644 --- a/src/buf/reader.rs +++ b/src/buf/reader.rs @@ -1,5 +1,6 @@ use {Buf}; +#[cfg(feature = "std")] use std::{cmp, io}; /// A `Buf` adapter which implements `io::Read` for the inner value. @@ -78,6 +79,7 @@ impl Reader { } } +#[cfg(feature = "std")] impl io::Read for Reader { fn read(&mut self, dst: &mut [u8]) -> io::Result { let len = cmp::min(self.buf.remaining(), dst.len()); @@ -87,6 +89,7 @@ impl io::Read for Reader { } } +#[cfg(feature = "std")] impl io::BufRead for Reader { fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(self.buf.bytes()) diff --git a/src/buf/take.rs b/src/buf/take.rs index a0c8ed479..a0babace5 100644 --- a/src/buf/take.rs +++ b/src/buf/take.rs @@ -1,6 +1,6 @@ use {Buf}; -use std::cmp; +use core::cmp; /// A `Buf` adapter which limits the bytes read from an underlying buffer. /// diff --git a/src/buf/vec_deque.rs b/src/buf/vec_deque.rs index 1cd650f51..ad8f31342 100644 --- a/src/buf/vec_deque.rs +++ b/src/buf/vec_deque.rs @@ -24,6 +24,7 @@ impl Buf for VecDeque { #[cfg(test)] mod tests { use super::*; + use prelude::*; #[test] fn hello_world() { diff --git a/src/buf/writer.rs b/src/buf/writer.rs index 38a739aa6..18279b47c 100644 --- a/src/buf/writer.rs +++ b/src/buf/writer.rs @@ -1,5 +1,6 @@ use BufMut; +#[cfg(feature = "std")] use std::{cmp, io}; /// A `BufMut` adapter which implements `io::Write` for the inner value. @@ -74,6 +75,7 @@ impl Writer { } } +#[cfg(feature = "std")] impl io::Write for Writer { fn write(&mut self, src: &[u8]) -> io::Result { let n = cmp::min(self.buf.remaining_mut(), src.len()); diff --git a/src/bytes.rs b/src/bytes.rs index a9aefa9d5..a3e4632c1 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -1,6 +1,7 @@ use {IntoBuf, Buf, BufMut}; use buf::Iter; use debug; +use prelude::*; use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize}; use std::borrow::{Borrow, BorrowMut}; @@ -1499,7 +1500,7 @@ impl BytesMut { } unsafe { - ptr = self.inner.ptr.offset(self.inner.len as isize); + ptr = self.inner.ptr.offset(self.inner.len as isize); } if ptr == other.inner.ptr && self.inner.kind() == KIND_ARC && diff --git a/src/lib.rs b/src/lib.rs index a4f1573e0..164acfac4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,9 +70,13 @@ #![deny(warnings, missing_docs, missing_debug_implementations)] #![doc(html_root_url = "https://docs.rs/bytes/0.4.12")] +#![no_std] extern crate byteorder; +#[cfg(feature = "iovec")] extern crate iovec; +#[cfg(feature = "std")] +extern crate std; pub mod buf; pub use buf::{ @@ -88,9 +92,13 @@ pub use buf::{ Take, }; +#[cfg(feature = "std")] mod bytes; +#[cfg(feature = "std")] mod debug; +#[cfg(feature = "std")] pub use bytes::{Bytes, BytesMut}; +mod prelude; #[deprecated] pub use byteorder::{ByteOrder, BigEndian, LittleEndian}; diff --git a/src/prelude.rs b/src/prelude.rs new file mode 100644 index 000000000..1ea00b8fb --- /dev/null +++ b/src/prelude.rs @@ -0,0 +1,5 @@ +//! Crate-local import prelude, primarily intended as a facade for accessing +//! heap-allocated data structures. + +#[cfg(feature = "std")] +pub use std::prelude::v1::*; diff --git a/src/serde.rs b/src/serde.rs index d45caff05..f0bdb00dc 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -1,8 +1,9 @@ extern crate serde; -use std::{cmp, fmt}; +use core::{cmp, fmt}; use self::serde::{Serialize, Serializer, Deserialize, Deserializer, de}; use super::{Bytes, BytesMut}; +use prelude::*; macro_rules! serde_impl { ($ty:ident, $visitor_ty:ident) => ( From a9a6345fbacb29101a586c714666cb08324ddfaa Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Apr 2019 09:17:17 -0700 Subject: [PATCH 2/2] alloc support (for no_std environments) 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'. --- .travis.yml | 4 ++++ Cargo.toml | 3 ++- src/buf/buf.rs | 4 ++-- src/buf/buf_mut.rs | 7 ++++--- src/buf/from_buf.rs | 10 +++++----- src/buf/mod.rs | 2 +- src/buf/vec_deque.rs | 3 +++ src/bytes.rs | 25 +++++++++++++++++++------ src/debug.rs | 2 +- src/lib.rs | 10 ++++++---- src/prelude.rs | 7 +++++++ tests/test_buf.rs | 9 +++++++++ tests/test_buf_mut.rs | 11 ++++++++++- tests/test_bytes.rs | 12 ++++++++++-- tests/test_chain.rs | 10 +++++++++- tests/test_from_buf.rs | 7 +++++++ tests/test_iter.rs | 3 +++ tests/test_reader.rs | 5 ++++- tests/test_take.rs | 3 +++ 19 files changed, 109 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index e332ce1f3..96c582ec4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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" diff --git a/Cargo.toml b/Cargo.toml index 3dc10d857..0fdf22e4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,5 +38,6 @@ serde_test = "1.0" [features] default = ["std"] +alloc = [] i128 = ["byteorder/i128"] -std = ["iovec"] +std = ["alloc", "iovec"] diff --git a/src/buf/buf.rs b/src/buf/buf.rs index 06738d668..888f6f4a9 100644 --- a/src/buf/buf.rs +++ b/src/buf/buf.rs @@ -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}; @@ -1077,7 +1077,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T { } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl Buf for Box { fn remaining(&self) -> usize { (**self).remaining() diff --git a/src/buf/buf_mut.rs b/src/buf/buf_mut.rs index 265b66668..bef36bd87 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -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}; @@ -1088,7 +1088,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T { } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl BufMut for Box { fn remaining_mut(&self) -> usize { (**self).remaining_mut() @@ -1098,6 +1098,7 @@ impl BufMut for Box { (**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) } @@ -1136,7 +1137,7 @@ impl + AsRef<[u8]>> BufMut for io::Cursor { } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl BufMut for Vec { #[inline] fn remaining_mut(&self) -> usize { diff --git a/src/buf/from_buf.rs b/src/buf/from_buf.rs index 58e8d2374..7d4accca8 100644 --- a/src/buf/from_buf.rs +++ b/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`] @@ -90,7 +90,7 @@ pub trait FromBuf { fn from_buf(buf: T) -> Self where T: IntoBuf; } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl FromBuf for Vec { fn from_buf(buf: T) -> Self where T: IntoBuf @@ -102,7 +102,7 @@ impl FromBuf for Vec { } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl FromBuf for Bytes { fn from_buf(buf: T) -> Self where T: IntoBuf @@ -111,7 +111,7 @@ impl FromBuf for Bytes { } } -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] impl FromBuf for BytesMut { fn from_buf(buf: T) -> Self where T: IntoBuf diff --git a/src/buf/mod.rs b/src/buf/mod.rs index efa7d0b2d..f2792de2f 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -24,7 +24,7 @@ mod into_buf; mod iter; mod reader; mod take; -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] mod vec_deque; mod writer; diff --git a/src/buf/vec_deque.rs b/src/buf/vec_deque.rs index ad8f31342..0669bf3c4 100644 --- a/src/buf/vec_deque.rs +++ b/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; diff --git a/src/bytes.rs b/src/bytes.rs index a3e4632c1..1c7357251 100644 --- a/src/bytes.rs +++ b/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. /// @@ -835,6 +840,7 @@ impl Bytes { } } +#[cfg(feature = "std")] impl IntoBuf for Bytes { type Buf = Cursor; @@ -843,6 +849,7 @@ impl IntoBuf for Bytes { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a Bytes { type Buf = Cursor; @@ -986,6 +993,7 @@ impl Borrow<[u8]> for Bytes { } } +#[cfg(feature = "std")] impl IntoIterator for Bytes { type Item = u8; type IntoIter = Iter>; @@ -995,6 +1003,7 @@ impl IntoIterator for Bytes { } } +#[cfg(feature = "std")] impl<'a> IntoIterator for &'a Bytes { type Item = u8; type IntoIter = Iter>; @@ -1563,6 +1572,7 @@ impl BufMut for BytesMut { } } +#[cfg(feature = "std")] impl IntoBuf for BytesMut { type Buf = Cursor; @@ -1571,6 +1581,7 @@ impl IntoBuf for BytesMut { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a BytesMut { type Buf = Cursor<&'a BytesMut>; @@ -1736,6 +1747,7 @@ impl Clone for BytesMut { } } +#[cfg(feature = "std")] impl IntoIterator for BytesMut { type Item = u8; type IntoIter = Iter>; @@ -1745,6 +1757,7 @@ impl IntoIterator for BytesMut { } } +#[cfg(feature = "std")] impl<'a> IntoIterator for &'a BytesMut { type Item = u8; type IntoIter = Iter>; diff --git a/src/debug.rs b/src/debug.rs index f8b830a24..08ee4d9dc 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,4 +1,4 @@ -use std::fmt; +use core::fmt; /// Alternative implementation of `fmt::Debug` for byte slice. /// diff --git a/src/lib.rs b/src/lib.rs index 164acfac4..5d34cd3c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,6 +72,8 @@ #![doc(html_root_url = "https://docs.rs/bytes/0.4.12")] #![no_std] +#[cfg(all(feature = "alloc", not(feature = "std")))] +extern crate alloc; extern crate byteorder; #[cfg(feature = "iovec")] extern crate iovec; @@ -92,13 +94,13 @@ pub use buf::{ Take, }; -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] mod bytes; -#[cfg(feature = "std")] +#[cfg(feature = "alloc")] 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}; diff --git a/src/prelude.rs b/src/prelude.rs index 1ea00b8fb..8b52a865d 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -1,5 +1,12 @@ //! Crate-local import prelude, primarily intended as a facade for accessing //! heap-allocated data structures. +#[cfg(all(feature = "alloc", not(feature = "std")))] +pub use alloc::boxed::Box; +#[cfg(all(feature = "alloc", not(feature = "std")))] +pub use alloc::string::String; +#[cfg(all(feature = "alloc", not(feature = "std")))] +pub use alloc::vec::Vec; + #[cfg(feature = "std")] pub use std::prelude::v1::*; diff --git a/tests/test_buf.rs b/tests/test_buf.rs index f25c25f2b..16d3c1f19 100644 --- a/tests/test_buf.rs +++ b/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()); @@ -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()); @@ -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"); diff --git a/tests/test_buf_mut.rs b/tests/test_buf_mut.rs index 2c8faa104..e985e546d 100644 --- a/tests/test_buf_mut.rs +++ b/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); @@ -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(); @@ -71,6 +79,7 @@ fn test_clone() { } #[test] +#[cfg(feature = "iovec")] fn test_bufs_vec_mut() { use std::mem; diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index e1883543f..935e8c9f7 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -1,6 +1,8 @@ extern crate bytes; -use bytes::{Bytes, BytesMut, BufMut, IntoBuf}; +use bytes::{Bytes, BytesMut, BufMut}; +#[cfg(feature = "std")] +use bytes::IntoBuf; const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb"; const SHORT: &'static [u8] = b"hello world"; @@ -166,6 +168,7 @@ fn split_off_uninitialized() { } #[test] +#[cfg(feature = "std")] fn split_off_to_loop() { let s = b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -299,6 +302,7 @@ fn fns_defined_for_bytes_mut() { } #[test] +#[cfg(feature = "std")] fn mut_into_buf() { let mut v = vec![0, 0, 0, 0]; let s = &mut v[..]; @@ -306,6 +310,7 @@ fn mut_into_buf() { } #[test] +#[cfg(feature = "std")] fn reserve_convert() { // Inline -> Vec let mut bytes = BytesMut::with_capacity(8); @@ -341,6 +346,7 @@ fn reserve_convert() { } #[test] +#[cfg(feature = "std")] fn reserve_growth() { let mut bytes = BytesMut::with_capacity(64); bytes.put("hello world"); @@ -385,6 +391,7 @@ fn reserve_max_original_capacity_value() { // within the program that this actually recycles memory. Instead, just exercise // the code path to ensure that the results are correct. #[test] +#[cfg(feature = "std")] fn reserve_vec_recycling() { let mut bytes = BytesMut::from(Vec::with_capacity(16)); assert_eq!(bytes.capacity(), 16); @@ -432,6 +439,7 @@ fn reserve_in_arc_nonunique_does_not_overallocate() { } #[test] +#[cfg(feature = "std")] fn inline_storage() { let mut bytes = BytesMut::with_capacity(inline_cap()); let zero = [0u8; 64]; @@ -524,7 +532,7 @@ fn advance_past_len() { #[test] // Only run these tests on little endian systems. CI uses qemu for testing // little endian... and qemu doesn't really support threading all that well. -#[cfg(target_endian = "little")] +#[cfg(all(target_endian = "little", feature = "std"))] fn stress() { // Tests promoting a buffer from a vec -> shared in a concurrent situation use std::sync::{Arc, Barrier}; diff --git a/tests/test_chain.rs b/tests/test_chain.rs index 2789e7c06..279940f28 100644 --- a/tests/test_chain.rs +++ b/tests/test_chain.rs @@ -1,12 +1,18 @@ extern crate bytes; +#[cfg(feature = "iovec")] extern crate iovec; -use bytes::{Buf, BufMut, Bytes, BytesMut}; +use bytes::{BufMut, BytesMut}; +#[cfg(feature = "std")] +use bytes::{Buf, Bytes}; use bytes::buf::Chain; +#[cfg(feature = "iovec")] use iovec::IoVec; +#[cfg(feature = "std")] use std::io::Cursor; #[test] +#[cfg(feature = "std")] fn collect_two_bufs() { let a = Cursor::new(Bytes::from(&b"hello"[..])); let b = Cursor::new(Bytes::from(&b"world"[..])); @@ -39,6 +45,7 @@ fn writing_chained() { } #[test] +#[cfg(feature = "std")] fn iterating_two_bufs() { let a = Cursor::new(Bytes::from(&b"hello"[..])); let b = Cursor::new(Bytes::from(&b"world"[..])); @@ -48,6 +55,7 @@ fn iterating_two_bufs() { } #[test] +#[cfg(feature = "std")] fn vectored_read() { let a = Cursor::new(Bytes::from(&b"hello"[..])); let b = Cursor::new(Bytes::from(&b"world"[..])); diff --git a/tests/test_from_buf.rs b/tests/test_from_buf.rs index 216bf1232..0b73456ea 100644 --- a/tests/test_from_buf.rs +++ b/tests/test_from_buf.rs @@ -1,12 +1,17 @@ extern crate bytes; +#[cfg(feature = "std")] use bytes::{Buf, Bytes, BytesMut}; +#[cfg(feature = "std")] use std::io::Cursor; +#[cfg(feature = "std")] const LONG: &'static [u8] = b"mary had a little lamb, little lamb, little lamb"; +#[cfg(feature = "std")] const SHORT: &'static [u8] = b"hello world"; #[test] +#[cfg(feature = "std")] fn collect_to_vec() { let buf: Vec = Cursor::new(SHORT).collect(); assert_eq!(buf, SHORT); @@ -16,6 +21,7 @@ fn collect_to_vec() { } #[test] +#[cfg(feature = "std")] fn collect_to_bytes() { let buf: Bytes = Cursor::new(SHORT).collect(); assert_eq!(buf, SHORT); @@ -25,6 +31,7 @@ fn collect_to_bytes() { } #[test] +#[cfg(feature = "std")] fn collect_to_bytes_mut() { let buf: BytesMut = Cursor::new(SHORT).collect(); assert_eq!(buf, SHORT); diff --git a/tests/test_iter.rs b/tests/test_iter.rs index c16dbf694..3243c2fd5 100644 --- a/tests/test_iter.rs +++ b/tests/test_iter.rs @@ -1,8 +1,10 @@ extern crate bytes; +#[cfg(feature = "std")] use bytes::{Buf, IntoBuf, Bytes}; #[test] +#[cfg(feature = "std")] fn iter_len() { let buf = Bytes::from(&b"hello world"[..]).into_buf(); let iter = buf.iter(); @@ -13,6 +15,7 @@ fn iter_len() { #[test] +#[cfg(feature = "std")] fn empty_iter_len() { let buf = Bytes::from(&b""[..]).into_buf(); let iter = buf.iter(); diff --git a/tests/test_reader.rs b/tests/test_reader.rs index 7103f3592..4247c629c 100644 --- a/tests/test_reader.rs +++ b/tests/test_reader.rs @@ -1,10 +1,12 @@ extern crate bytes; +#[cfg(feature = "std")] use std::io::{BufRead, Cursor, Read}; - +#[cfg(feature = "std")] use bytes::Buf; #[test] +#[cfg(feature = "std")] fn read() { let buf1 = Cursor::new(b"hello "); let buf2 = Cursor::new(b"world"); @@ -15,6 +17,7 @@ fn read() { } #[test] +#[cfg(feature = "std")] fn buf_read() { let buf1 = Cursor::new(b"hell"); let buf2 = Cursor::new(b"o\nworld"); diff --git a/tests/test_take.rs b/tests/test_take.rs index 93e0c6c5a..bbc197a9c 100644 --- a/tests/test_take.rs +++ b/tests/test_take.rs @@ -1,9 +1,12 @@ extern crate bytes; +#[cfg(feature = "std")] use bytes::Buf; +#[cfg(feature = "std")] use std::io::Cursor; #[test] +#[cfg(feature = "std")] fn long_take() { // Tests that take with a size greater than the buffer length will not // overrun the buffer. Regression test for #138.