From 18f2a7e05a6e97e09215a9a59e63eb5cb7f40ea6 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 14 Apr 2019 07:53:39 -0700 Subject: [PATCH] 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) => (