Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

no_std support (using enabled-by-default "std" feature) #135

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Expand Up @@ -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:
Expand Down
11 changes: 9 additions & 2 deletions Cargo.toml
Expand Up @@ -17,12 +17,19 @@ exclude = [
"bench/**/*",
"test/**/*"
]
categories = ["network-programming", "data-structures"]
categories = ["network-programming", "data-structures", "no-std"]

[dependencies]
byteorder = "1.0.0"
iovec = "0.1"
serde = { version = "1.0", optional = true }

[dependencies.iovec]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so this means that the vectored IO fns on the traits aren't available, which doesn't seem great (long term).

That said, they could be brought back incrementally w/o a breaking change.

version = "0.1"
optional = true

[dev-dependencies]
serde_test = "1.0"

[features]
default = ["std"]
std = ["iovec"]
19 changes: 16 additions & 3 deletions 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.
///
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -520,6 +528,7 @@ pub trait Buf {
///
/// assert_eq!(vec, &b"hello world"[..]);
/// ```
#[cfg(feature = "std")]
fn collect<B>(self) -> B
where Self: Sized,
B: FromBuf,
Expand Down Expand Up @@ -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)
}
Expand All @@ -671,6 +681,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T {
}
}

#[cfg(feature = "std")]
impl<T: Buf + ?Sized> Buf for Box<T> {
fn remaining(&self) -> usize {
(**self).remaining()
Expand All @@ -680,6 +691,7 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
(**self).bytes()
}

#[cfg(feature = "std")]
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
(**self).bytes_vec(dst)
}
Expand All @@ -689,6 +701,7 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
}
}

#[cfg(feature = "std")]
impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
fn remaining(&self) -> usize {
let len = self.get_ref().as_ref().len();
Expand Down
14 changes: 12 additions & 2 deletions 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.
///
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}
Expand All @@ -654,6 +660,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T {
}
}

#[cfg(feature = "std")]
impl<T: BufMut + ?Sized> BufMut for Box<T> {
fn remaining_mut(&self) -> usize {
(**self).remaining_mut()
Expand All @@ -663,6 +670,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<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)
}
Expand All @@ -672,6 +680,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
}
}

#[cfg(feature = "std")]
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
fn remaining_mut(&self) -> usize {
use Buf;
Expand Down Expand Up @@ -700,6 +709,7 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
}
}

#[cfg(feature = "std")]
impl BufMut for Vec<u8> {
#[inline]
fn remaining_mut(&self) -> usize {
Expand All @@ -721,7 +731,7 @@ impl BufMut for Vec<u8> {

#[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
Expand Down
3 changes: 3 additions & 0 deletions src/buf/chain.rs
@@ -1,4 +1,5 @@
use {Buf, BufMut};
#[cfg(feature = "std")]
use iovec::IoVec;

/// A `Chain` sequences two buffers.
Expand Down Expand Up @@ -177,6 +178,7 @@ impl<T, U> Buf for Chain<T, U>
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..]);
Expand Down Expand Up @@ -218,6 +220,7 @@ impl<T, U> BufMut for Chain<T, U>
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..]);
Expand Down
9 changes: 9 additions & 0 deletions src/buf/into_buf.rs
@@ -1,5 +1,6 @@
use super::{Buf};

#[cfg(feature = "std")]
use std::io;

/// Conversion into a `Buf`
Expand Down Expand Up @@ -55,6 +56,7 @@ impl<T: Buf> IntoBuf for T {
}
}

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

Expand All @@ -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]>;

Expand All @@ -71,6 +74,7 @@ impl<'a> IntoBuf for &'a str {
}
}

#[cfg(feature = "std")]
impl IntoBuf for Vec<u8> {
type Buf = io::Cursor<Vec<u8>>;

Expand All @@ -79,6 +83,7 @@ impl IntoBuf for Vec<u8> {
}
}

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

Expand All @@ -89,6 +94,7 @@ impl<'a> IntoBuf for &'a Vec<u8> {

// 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]>;

Expand All @@ -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]>;

Expand All @@ -105,6 +112,7 @@ impl<'a> IntoBuf for &'a &'static str {
}
}

#[cfg(feature = "std")]
impl IntoBuf for String {
type Buf = io::Cursor<Vec<u8>>;

Expand All @@ -113,6 +121,7 @@ impl IntoBuf for String {
}
}

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

Expand Down
2 changes: 2 additions & 0 deletions src/buf/mod.rs
Expand Up @@ -18,6 +18,7 @@

mod buf;
mod buf_mut;
#[cfg(feature = "std")]
mod from_buf;
mod chain;
mod into_buf;
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions 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.
Expand Down Expand Up @@ -78,6 +79,7 @@ impl<B: Buf> Reader<B> {
}
}

#[cfg(feature = "std")]
impl<B: Buf + Sized> io::Read for Reader<B> {
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
let len = cmp::min(self.buf.remaining(), dst.len());
Expand Down
2 changes: 1 addition & 1 deletion 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.
///
Expand Down
2 changes: 2 additions & 0 deletions 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.
Expand Down Expand Up @@ -74,6 +75,7 @@ impl<B: BufMut> Writer<B> {
}
}

#[cfg(feature = "std")]
impl<B: BufMut + Sized> io::Write for Writer<B> {
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
let n = cmp::min(self.buf.remaining_mut(), src.len());
Expand Down