From 2c6b1d8b58de01f9ab2e5bb26c9cde17b49ee375 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Jun 2017 16:00:54 -0700 Subject: [PATCH 1/2] no_std support (using enabled-by-default "std" feature) - Changes all references to libcore features from ::std to ::core - Feature gates anything dependent on std on the "std" feature --- .travis.yml | 4 ++++ Cargo.toml | 10 +++++++++- src/buf/buf.rs | 19 ++++++++++++++++--- src/buf/buf_mut.rs | 14 ++++++++++++-- src/buf/chain.rs | 3 +++ src/buf/into_buf.rs | 9 +++++++++ src/buf/mod.rs | 2 ++ src/buf/reader.rs | 2 ++ src/buf/take.rs | 2 +- src/buf/writer.rs | 2 ++ src/bytes.rs | 42 ++++++++++++++++++++++-------------------- src/debug.rs | 2 +- src/lib.rs | 9 +++++++++ 13 files changed, 92 insertions(+), 28 deletions(-) diff --git a/.travis.yml b/.travis.yml index eb0d1eb58..2e42d7bc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,10 @@ matrix: # Serde implementation - env: EXTRA_ARGS="--features serde" + # Ensure crate compiles without default features (i.e. for no_std) + - env: EXTRA_ARGS="--no-default-features" + script: cargo build $EXTRA_ARGS + before_install: set -e install: diff --git a/Cargo.toml b/Cargo.toml index 07c58c025..d6b605009 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ documentation = "https://carllerche.github.io/bytes/bytes" homepage = "https://github.com/carllerche/bytes" repository = "https://github.com/carllerche/bytes" readme = "README.md" +categories = ["no-std"] keywords = ["buffers", "zero-copy", "io"] exclude = [ ".gitignore", @@ -21,8 +22,15 @@ categories = ["network-programming", "data-structures"] [dependencies] byteorder = "1.0.0" -iovec = "0.1" serde = { version = "1.0", optional = true } +[dependencies.iovec] +version = "0.1" +optional = true + [dev-dependencies] serde_test = "1.0" + +[features] +default = ["std"] +std = ["iovec"] diff --git a/src/buf/buf.rs b/src/buf/buf.rs index 42280e793..6b9ae457c 100644 --- a/src/buf/buf.rs +++ b/src/buf/buf.rs @@ -1,8 +1,15 @@ -use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain}; +use super::{IntoBuf, Take, Reader, Iter, Chain}; +#[cfg(feature = "std")] +use super::FromBuf; + use byteorder::ByteOrder; +#[cfg(feature = "std")] use iovec::IoVec; -use std::{cmp, io, ptr}; +use core::{cmp, ptr}; + +#[cfg(feature = "std")] +use std::io; /// Read bytes from a buffer. /// @@ -12,7 +19,7 @@ use std::{cmp, io, ptr}; /// position. It can be thought of as an efficient `Iterator` for collections of /// bytes. /// -/// The simplest `Buf` is a `Cursor` wrapping a `[u8]`. +/// The simplest `Buf` is a `io::Cursor` wrapping a `[u8]`. /// /// ``` /// use bytes::Buf; @@ -113,6 +120,7 @@ pub trait Buf { /// with `dst` being a zero length slice. /// /// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html + #[cfg(feature = "std")] fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize { if dst.is_empty() { return 0; @@ -520,6 +528,7 @@ pub trait Buf { /// /// assert_eq!(vec, &b"hello world"[..]); /// ``` + #[cfg(feature = "std")] fn collect(self) -> B where Self: Sized, B: FromBuf, @@ -662,6 +671,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T { (**self).bytes() } + #[cfg(feature = "std")] fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize { (**self).bytes_vec(dst) } @@ -671,6 +681,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T { } } +#[cfg(feature = "std")] impl Buf for Box { fn remaining(&self) -> usize { (**self).remaining() @@ -680,6 +691,7 @@ impl Buf for Box { (**self).bytes() } + #[cfg(feature = "std")] fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize { (**self).bytes_vec(dst) } @@ -689,6 +701,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 b03103a61..c480be823 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1,8 +1,12 @@ use super::{IntoBuf, Writer}; use byteorder::ByteOrder; +#[cfg(feature = "std")] use iovec::IoVec; -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. /// @@ -188,6 +192,7 @@ pub trait BufMut { /// with `dst` being a zero length slice. /// /// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html + #[cfg(feature = "std")] unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize { if dst.is_empty() { return 0; @@ -645,6 +650,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T { (**self).bytes_mut() } + #[cfg(feature = "std")] unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize { (**self).bytes_vec_mut(dst) } @@ -654,6 +660,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() @@ -663,6 +670,7 @@ impl BufMut for Box { (**self).bytes_mut() } + #[cfg(feature = "std")] unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize { (**self).bytes_vec_mut(dst) } @@ -672,6 +680,7 @@ impl BufMut for Box { } } +#[cfg(feature = "std")] impl + AsRef<[u8]>> BufMut for io::Cursor { fn remaining_mut(&self) -> usize { use Buf; @@ -700,6 +709,7 @@ impl + AsRef<[u8]>> BufMut for io::Cursor { } } +#[cfg(feature = "std")] impl BufMut for Vec { #[inline] fn remaining_mut(&self) -> usize { @@ -721,7 +731,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..22fe04232 100644 --- a/src/buf/chain.rs +++ b/src/buf/chain.rs @@ -1,4 +1,5 @@ use {Buf, BufMut}; +#[cfg(feature = "std")] use iovec::IoVec; /// A `Chain` sequences two buffers. @@ -177,6 +178,7 @@ impl Buf for Chain self.b.advance(cnt); } + #[cfg(feature = "std")] 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 = "std")] 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/into_buf.rs b/src/buf/into_buf.rs index 1071908a2..5742978e1 100644 --- a/src/buf/into_buf.rs +++ b/src/buf/into_buf.rs @@ -1,5 +1,6 @@ use super::{Buf}; +#[cfg(feature = "std")] use std::io; /// Conversion into a `Buf` @@ -55,6 +56,7 @@ impl IntoBuf for T { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a [u8] { type Buf = io::Cursor<&'a [u8]>; @@ -63,6 +65,7 @@ impl<'a> IntoBuf for &'a [u8] { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a str { type Buf = io::Cursor<&'a [u8]>; @@ -71,6 +74,7 @@ impl<'a> IntoBuf for &'a str { } } +#[cfg(feature = "std")] impl IntoBuf for Vec { type Buf = io::Cursor>; @@ -79,6 +83,7 @@ impl IntoBuf for Vec { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a Vec { type Buf = io::Cursor<&'a [u8]>; @@ -89,6 +94,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]>; @@ -97,6 +103,7 @@ impl<'a> IntoBuf for &'a &'static [u8] { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a &'static str { type Buf = io::Cursor<&'static [u8]>; @@ -105,6 +112,7 @@ impl<'a> IntoBuf for &'a &'static str { } } +#[cfg(feature = "std")] impl IntoBuf for String { type Buf = io::Cursor>; @@ -113,6 +121,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 1f74e0ab4..335f51962 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -18,6 +18,7 @@ mod buf; mod buf_mut; +#[cfg(feature = "std")] mod from_buf; mod chain; mod into_buf; @@ -28,6 +29,7 @@ mod writer; pub use self::buf::Buf; pub use self::buf_mut::BufMut; +#[cfg(feature = "std")] pub use self::from_buf::FromBuf; pub use self::chain::Chain; pub use self::into_buf::IntoBuf; diff --git a/src/buf/reader.rs b/src/buf/reader.rs index 59f9c3304..771f967f0 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()); 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/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 ac6559268..721d5f477 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -2,12 +2,14 @@ use {IntoBuf, Buf, BufMut}; use buf::Iter; use debug; -use std::{cmp, fmt, mem, hash, ops, slice, ptr, usize}; -use std::borrow::Borrow; -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}; +use core::{cmp, fmt, mem, hash, ops, slice, ptr, usize}; +use core::borrow::Borrow; +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; /// A reference counted contiguous slice of memory. /// @@ -311,10 +313,10 @@ struct Inner { } // Thread-safe reference-counted container for the shared storage. This mostly -// the same as `std::sync::Arc` but without the weak counter. The ref counting +// the same as `core::sync::Arc` but without the weak counter. The ref counting // fns are based on the ones found in `std`. // -// The main reason to use `Shared` instead of `std::sync::Arc` is that it ends +// The main reason to use `Shared` instead of `core::sync::Arc` is that it ends // up making the overall code simpler and easier to reason about. This is due to // some of the logic around setting `Inner::arc` and other ways the `arc` field // is used. Using `Arc` ended up requiring a number of funky transmutes and @@ -750,18 +752,18 @@ impl Bytes { } impl IntoBuf for Bytes { - type Buf = Cursor; + type Buf = io::Cursor; fn into_buf(self) -> Self::Buf { - Cursor::new(self) + io::Cursor::new(self) } } impl<'a> IntoBuf for &'a Bytes { - type Buf = Cursor; + type Buf = io::Cursor; fn into_buf(self) -> Self::Buf { - Cursor::new(self) + io::Cursor::new(self) } } @@ -889,7 +891,7 @@ impl Borrow<[u8]> for Bytes { impl IntoIterator for Bytes { type Item = u8; - type IntoIter = Iter>; + type IntoIter = Iter>; fn into_iter(self) -> Self::IntoIter { self.into_buf().iter() @@ -898,7 +900,7 @@ impl IntoIterator for Bytes { impl<'a> IntoIterator for &'a Bytes { type Item = u8; - type IntoIter = Iter>; + type IntoIter = Iter>; fn into_iter(self) -> Self::IntoIter { self.into_buf().iter() @@ -1372,18 +1374,18 @@ impl BufMut for BytesMut { } impl IntoBuf for BytesMut { - type Buf = Cursor; + type Buf = io::Cursor; fn into_buf(self) -> Self::Buf { - Cursor::new(self) + io::Cursor::new(self) } } impl<'a> IntoBuf for &'a BytesMut { - type Buf = Cursor<&'a BytesMut>; + type Buf = io::Cursor<&'a BytesMut>; fn into_buf(self) -> Self::Buf { - Cursor::new(self) + io::Cursor::new(self) } } @@ -1540,7 +1542,7 @@ impl Clone for BytesMut { impl IntoIterator for BytesMut { type Item = u8; - type IntoIter = Iter>; + type IntoIter = Iter>; fn into_iter(self) -> Self::IntoIter { self.into_buf().iter() @@ -1549,7 +1551,7 @@ impl IntoIterator for BytesMut { impl<'a> IntoIterator for &'a BytesMut { type Item = u8; - type IntoIter = Iter>; + type IntoIter = Iter>; fn into_iter(self) -> Self::IntoIter { self.into_buf().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 fbe65721a..8227e8011 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,8 +70,13 @@ #![deny(warnings, missing_docs, missing_debug_implementations)] #![doc(html_root_url = "https://docs.rs/bytes/0.4")] +#![cfg_attr(not(feature = "std"), no_std)] extern crate byteorder; + +#[cfg(feature = "std")] +extern crate core; +#[cfg(feature = "std")] extern crate iovec; pub mod buf; @@ -88,8 +93,12 @@ pub use buf::{ Take, }; +#[cfg(feature = "std")] mod bytes; +#[cfg(feature = "std")] mod debug; + +#[cfg(feature = "std")] pub use bytes::{Bytes, BytesMut}; pub use byteorder::{ByteOrder, BigEndian, LittleEndian}; From a90575c7cba8764a89b8afaf2a9a081d5fb12dc2 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 17 Jul 2017 18:54:01 -0700 Subject: [PATCH 2/2] "allocator" and "nightly" features (for no_std environments) This commit gates all allocator-dependent features on an "allocator" feature. It also adds a "nightly" feature which enables using the "allocator" feature in no_std environments. This requires using #[feature(alloc)] which requires nightly. The "allocator" feature is automatically enabled when either the "std" or "nightly" features are enabled. Travis CI is configured to check that builds succeed with both the "nightly" feature along with "std" and "nightly" in combination. To avoid the problem of nightly changes breaking the build, these combinations are specifically flagged as allowed failures in the Travis CI configuration. --- .travis.yml | 19 +++++++++++++++++++ Cargo.toml | 7 ++++--- src/buf/buf.rs | 9 ++++++--- src/buf/buf_mut.rs | 8 ++++++-- src/buf/from_buf.rs | 3 +++ src/buf/mod.rs | 4 ++-- src/bytes.rs | 16 +++++++++++++++- src/lib.rs | 21 ++++++++++++++++++--- 8 files changed, 73 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e42d7bc0..71c988994 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,25 @@ matrix: - env: EXTRA_ARGS="--no-default-features" script: cargo build $EXTRA_ARGS + # Ensure crate compiles with "nightly" feature (i.e. for allocation w\ no_std) + - env: EXTRA_ARGS="--no-default-features --features nightly" + script: cargo build $EXTRA_ARGS + rust: nightly + + # Ensure crate compiles with both "std" and "nightly" features + - env: EXTRA_ARGS="--no-default-features --features std,nightly" + script: cargo build $EXTRA_ARGS + rust: nightly + + # Allow "nightly" feature to fail (so we aren't blocked on upstream nightly changes) + allow_failures: + - env: EXTRA_ARGS="--no-default-features --features nightly" + script: cargo build $EXTRA_ARGS + rust: nightly + - env: EXTRA_ARGS="--no-default-features --features std,nightly" + script: cargo build $EXTRA_ARGS + rust: nightly + before_install: set -e install: diff --git a/Cargo.toml b/Cargo.toml index d6b605009..c515369c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,6 @@ documentation = "https://carllerche.github.io/bytes/bytes" homepage = "https://github.com/carllerche/bytes" repository = "https://github.com/carllerche/bytes" readme = "README.md" -categories = ["no-std"] keywords = ["buffers", "zero-copy", "io"] exclude = [ ".gitignore", @@ -18,7 +17,7 @@ exclude = [ "bench/**/*", "test/**/*" ] -categories = ["network-programming", "data-structures"] +categories = ["network-programming", "data-structures", "no-std"] [dependencies] byteorder = "1.0.0" @@ -32,5 +31,7 @@ optional = true serde_test = "1.0" [features] +allocator = [] default = ["std"] -std = ["iovec"] +nightly = ["allocator"] +std = ["allocator", "iovec"] diff --git a/src/buf/buf.rs b/src/buf/buf.rs index 6b9ae457c..da4c9a11a 100644 --- a/src/buf/buf.rs +++ b/src/buf/buf.rs @@ -1,5 +1,5 @@ use super::{IntoBuf, Take, Reader, Iter, Chain}; -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] use super::FromBuf; use byteorder::ByteOrder; @@ -11,6 +11,9 @@ use core::{cmp, ptr}; #[cfg(feature = "std")] use std::io; +#[allow(unused_imports)] +use prelude::*; + /// Read bytes from a buffer. /// /// A buffer stores bytes in memory such that read operations are infallible. @@ -528,7 +531,7 @@ pub trait Buf { /// /// assert_eq!(vec, &b"hello world"[..]); /// ``` - #[cfg(feature = "std")] + #[cfg(feature = "allocator")] fn collect(self) -> B where Self: Sized, B: FromBuf, @@ -681,7 +684,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T { } } -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] 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 c480be823..95c510ae3 100644 --- a/src/buf/buf_mut.rs +++ b/src/buf/buf_mut.rs @@ -1,5 +1,6 @@ use super::{IntoBuf, Writer}; use byteorder::ByteOrder; + #[cfg(feature = "std")] use iovec::IoVec; @@ -8,6 +9,9 @@ use core::{cmp, ptr, usize}; #[cfg(feature = "std")] use std::io; +#[allow(unused_imports)] +use prelude::*; + /// A trait for values that provide sequential write access to bytes. /// /// Write bytes to a buffer @@ -660,7 +664,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T { } } -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] impl BufMut for Box { fn remaining_mut(&self) -> usize { (**self).remaining_mut() @@ -709,7 +713,7 @@ impl + AsRef<[u8]>> BufMut for io::Cursor { } } -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] 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 55f5cef31..ea06eb34e 100644 --- a/src/buf/from_buf.rs +++ b/src/buf/from_buf.rs @@ -1,5 +1,8 @@ use {Buf, BufMut, IntoBuf, Bytes, BytesMut}; +#[allow(unused_imports)] +use prelude::*; + /// Conversion from a [`Buf`] /// /// Implementing `FromBuf` for a type defines how it is created from a buffer. diff --git a/src/buf/mod.rs b/src/buf/mod.rs index 335f51962..751b063ed 100644 --- a/src/buf/mod.rs +++ b/src/buf/mod.rs @@ -18,7 +18,7 @@ mod buf; mod buf_mut; -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] mod from_buf; mod chain; mod into_buf; @@ -29,7 +29,7 @@ mod writer; pub use self::buf::Buf; pub use self::buf_mut::BufMut; -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] pub use self::from_buf::FromBuf; pub use self::chain::Chain; pub use self::into_buf::IntoBuf; diff --git a/src/bytes.rs b/src/bytes.rs index 721d5f477..97a385e32 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -1,4 +1,7 @@ -use {IntoBuf, Buf, BufMut}; +#[cfg(feature = "std")] +use {IntoBuf, Buf}; +use BufMut; +#[cfg(feature = "std")] use buf::Iter; use debug; @@ -11,6 +14,9 @@ use core::iter::{FromIterator, Iterator}; #[cfg(feature = "std")] use std::io; +#[allow(unused_imports)] +use prelude::*; + /// A reference counted contiguous slice of memory. /// /// `Bytes` is an efficient container for storing and operating on contiguous @@ -751,6 +757,7 @@ impl Bytes { } } +#[cfg(feature = "std")] impl IntoBuf for Bytes { type Buf = io::Cursor; @@ -759,6 +766,7 @@ impl IntoBuf for Bytes { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a Bytes { type Buf = io::Cursor; @@ -889,6 +897,7 @@ impl Borrow<[u8]> for Bytes { } } +#[cfg(feature = "std")] impl IntoIterator for Bytes { type Item = u8; type IntoIter = Iter>; @@ -898,6 +907,7 @@ impl IntoIterator for Bytes { } } +#[cfg(feature = "std")] impl<'a> IntoIterator for &'a Bytes { type Item = u8; type IntoIter = Iter>; @@ -1373,6 +1383,7 @@ impl BufMut for BytesMut { } } +#[cfg(feature = "std")] impl IntoBuf for BytesMut { type Buf = io::Cursor; @@ -1381,6 +1392,7 @@ impl IntoBuf for BytesMut { } } +#[cfg(feature = "std")] impl<'a> IntoBuf for &'a BytesMut { type Buf = io::Cursor<&'a BytesMut>; @@ -1540,6 +1552,7 @@ impl Clone for BytesMut { } } +#[cfg(feature = "std")] impl IntoIterator for BytesMut { type Item = u8; type IntoIter = Iter>; @@ -1549,6 +1562,7 @@ impl IntoIterator for BytesMut { } } +#[cfg(feature = "std")] impl<'a> IntoIterator for &'a BytesMut { type Item = u8; type IntoIter = Iter>; diff --git a/src/lib.rs b/src/lib.rs index 8227e8011..6282189ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,9 +71,12 @@ #![deny(warnings, missing_docs, missing_debug_implementations)] #![doc(html_root_url = "https://docs.rs/bytes/0.4")] #![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(feature = "nightly", feature(alloc))] extern crate byteorder; +#[cfg(feature = "nightly")] +extern crate alloc; #[cfg(feature = "std")] extern crate core; #[cfg(feature = "std")] @@ -93,12 +96,12 @@ pub use buf::{ Take, }; -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] mod bytes; -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] mod debug; -#[cfg(feature = "std")] +#[cfg(feature = "allocator")] pub use bytes::{Bytes, BytesMut}; pub use byteorder::{ByteOrder, BigEndian, LittleEndian}; @@ -107,3 +110,15 @@ pub use byteorder::{ByteOrder, BigEndian, LittleEndian}; #[cfg(feature = "serde")] #[doc(hidden)] pub mod serde; + +/// Custom (internal-only) prelude for this module +mod prelude { + #[cfg(feature = "nightly")] + pub use alloc::boxed::Box; + + #[cfg(feature = "nightly")] + pub use alloc::string::String; + + #[cfg(feature = "nightly")] + pub use alloc::vec::Vec; +}