Skip to content

Commit e12c0b5

Browse files
committed
Support no_std w\ enabled-by-default "use_std" feature
- Changes all references to libcore features from ::std to ::core - Feature gates anything dependent on std::io on the "use_std" feature - Obtains Box, String, and Vec from libcollections in no_std environments - Vendors a tiny bit of std::io::cursor for use in no_std environments
1 parent 3240fb9 commit e12c0b5

15 files changed

+153
-27
lines changed

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ matrix:
3636
# Serde implementation
3737
- env: EXTRA_ARGS="--features serde"
3838

39+
# Ensure crate compiles without default features (i.e. for no_std)
40+
- script: cargo build --no-default-features
41+
rust: nightly
42+
3943
before_install: set -e
4044

4145
install:

Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,15 @@ categories = ["network-programming", "data-structures"]
2121

2222
[dependencies]
2323
byteorder = "1.0.0"
24-
iovec = "0.1"
2524
serde = { version = "1.0", optional = true }
2625

26+
[dependencies.iovec]
27+
version = "0.1"
28+
optional = true
29+
2730
[dev-dependencies]
2831
serde_test = "1.0"
32+
33+
[features]
34+
default = ["use_std"]
35+
use_std = ["iovec"]

src/buf/buf.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
use super::{IntoBuf, Take, Reader, Iter, FromBuf, Chain};
22
use byteorder::ByteOrder;
3+
#[cfg(feature = "use_std")]
34
use iovec::IoVec;
45

5-
use std::{cmp, io, ptr};
6+
#[cfg(not(feature = "use_std"))]
7+
use alloc::boxed::Box;
8+
use core::{cmp, ptr};
9+
#[cfg(not(feature = "use_std"))]
10+
use buf::Cursor;
11+
#[cfg(feature = "use_std")]
12+
use std::io::Cursor;
613

714
/// Read bytes from a buffer.
815
///
@@ -113,6 +120,7 @@ pub trait Buf {
113120
/// with `dst` being a zero length slice.
114121
///
115122
/// [`writev`]: http://man7.org/linux/man-pages/man2/readv.2.html
123+
#[cfg(feature = "use_std")]
116124
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
117125
if dst.is_empty() {
118126
return 0;
@@ -662,6 +670,7 @@ impl<'a, T: Buf + ?Sized> Buf for &'a mut T {
662670
(**self).bytes()
663671
}
664672

673+
#[cfg(feature = "use_std")]
665674
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
666675
(**self).bytes_vec(dst)
667676
}
@@ -680,6 +689,7 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
680689
(**self).bytes()
681690
}
682691

692+
#[cfg(feature = "use_std")]
683693
fn bytes_vec<'b>(&'b self, dst: &mut [&'b IoVec]) -> usize {
684694
(**self).bytes_vec(dst)
685695
}
@@ -689,7 +699,7 @@ impl<T: Buf + ?Sized> Buf for Box<T> {
689699
}
690700
}
691701

692-
impl<T: AsRef<[u8]>> Buf for io::Cursor<T> {
702+
impl<T: AsRef<[u8]>> Buf for Cursor<T> {
693703
fn remaining(&self) -> usize {
694704
let len = self.get_ref().as_ref().len();
695705
let pos = self.position();

src/buf/buf_mut.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
use super::{IntoBuf, Writer};
22
use byteorder::ByteOrder;
3+
#[cfg(feature = "use_std")]
34
use iovec::IoVec;
45

5-
use std::{cmp, io, ptr, usize};
6+
#[cfg(not(feature = "use_std"))]
7+
use alloc::boxed::Box;
8+
#[cfg(not(feature = "use_std"))]
9+
use alloc::vec::Vec;
10+
use core::{cmp, ptr, usize};
11+
#[cfg(not(feature = "use_std"))]
12+
use buf::Cursor;
13+
#[cfg(feature = "use_std")]
14+
use std::io::Cursor;
615

716
/// A trait for values that provide sequential write access to bytes.
817
///
@@ -188,6 +197,7 @@ pub trait BufMut {
188197
/// with `dst` being a zero length slice.
189198
///
190199
/// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html
200+
#[cfg(feature = "use_std")]
191201
unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
192202
if dst.is_empty() {
193203
return 0;
@@ -645,6 +655,7 @@ impl<'a, T: BufMut + ?Sized> BufMut for &'a mut T {
645655
(**self).bytes_mut()
646656
}
647657

658+
#[cfg(feature = "use_std")]
648659
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
649660
(**self).bytes_vec_mut(dst)
650661
}
@@ -663,6 +674,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
663674
(**self).bytes_mut()
664675
}
665676

677+
#[cfg(feature = "use_std")]
666678
unsafe fn bytes_vec_mut<'b>(&'b mut self, dst: &mut [&'b mut IoVec]) -> usize {
667679
(**self).bytes_vec_mut(dst)
668680
}
@@ -672,7 +684,7 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
672684
}
673685
}
674686

675-
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
687+
impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for Cursor<T> {
676688
fn remaining_mut(&self) -> usize {
677689
use Buf;
678690
self.remaining()
@@ -721,7 +733,7 @@ impl BufMut for Vec<u8> {
721733

722734
#[inline]
723735
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
724-
use std::slice;
736+
use core::slice;
725737

726738
if self.capacity() == self.len() {
727739
self.reserve(64); // Grow the vec

src/buf/chain.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use {Buf, BufMut};
2+
#[cfg(feature = "use_std")]
23
use iovec::IoVec;
34

45
/// A `Chain` sequences two buffers.
@@ -177,6 +178,7 @@ impl<T, U> Buf for Chain<T, U>
177178
self.b.advance(cnt);
178179
}
179180

181+
#[cfg(feature = "use_std")]
180182
fn bytes_vec<'a>(&'a self, dst: &mut [&'a IoVec]) -> usize {
181183
let mut n = self.a.bytes_vec(dst);
182184
n += self.b.bytes_vec(&mut dst[n..]);
@@ -218,6 +220,7 @@ impl<T, U> BufMut for Chain<T, U>
218220
self.b.advance_mut(cnt);
219221
}
220222

223+
#[cfg(feature = "use_std")]
221224
unsafe fn bytes_vec_mut<'a>(&'a mut self, dst: &mut [&'a mut IoVec]) -> usize {
222225
let mut n = self.a.bytes_vec_mut(dst);
223226
n += self.b.bytes_vec_mut(&mut dst[n..]);

src/buf/cursor.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// A `Cursor` wraps another type and provides it with a
12+
/// [`Seek`] implementation.
13+
///
14+
/// `Cursor`s are typically used with in-memory buffers to allow them to
15+
/// implement [`Read`] and/or [`Write`], allowing these buffers to be used
16+
/// anywhere you might use a reader or writer that does actual I/O.
17+
///
18+
/// The standard library implements some I/O traits on various types which
19+
/// are commonly used as a buffer, like `Cursor<`[`Vec`]`<u8>>` and
20+
/// `Cursor<`[`&[u8]`][bytes]`>`.
21+
#[derive(Clone, Debug)]
22+
pub struct Cursor<T> {
23+
inner: T,
24+
pos: u64,
25+
}
26+
27+
impl<T> Cursor<T> {
28+
/// Creates a new cursor wrapping the provided underlying I/O object.
29+
///
30+
/// Cursor initial position is `0` even if underlying object (e.
31+
/// g. `Vec`) is not empty. So writing to cursor starts with
32+
/// overwriting `Vec` content, not with appending to it.
33+
pub fn new(inner: T) -> Cursor<T> {
34+
Cursor { pos: 0, inner: inner }
35+
}
36+
37+
/// Consumes this cursor, returning the underlying value.
38+
pub fn into_inner(self) -> T { self.inner }
39+
40+
/// Gets a reference to the underlying value in this cursor.
41+
pub fn get_ref(&self) -> &T { &self.inner }
42+
43+
/// Gets a mutable reference to the underlying value in this cursor.
44+
///
45+
/// Care should be taken to avoid modifying the internal I/O state of the
46+
/// underlying value as it may corrupt this cursor's position.
47+
pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
48+
49+
/// Returns the current position of this cursor.
50+
pub fn position(&self) -> u64 { self.pos }
51+
52+
/// Sets the position of this cursor.
53+
pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
54+
}

src/buf/from_buf.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use {Buf, BufMut, IntoBuf, Bytes, BytesMut};
22

3+
#[cfg(not(feature = "use_std"))]
4+
use alloc::vec::Vec;
5+
36
/// Conversion from a [`Buf`]
47
///
58
/// Implementing `FromBuf` for a type defines how it is created from a buffer.

src/buf/into_buf.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
use super::{Buf};
22

3-
use std::io;
3+
#[cfg(not(feature = "use_std"))]
4+
use buf::Cursor;
5+
#[cfg(not(feature = "use_std"))]
6+
use alloc::string::String;
7+
#[cfg(not(feature = "use_std"))]
8+
use alloc::vec::Vec;
9+
#[cfg(feature = "use_std")]
10+
use std::io::Cursor;
411

512
/// Conversion into a `Buf`
613
///
@@ -56,65 +63,65 @@ impl<T: Buf> IntoBuf for T {
5663
}
5764

5865
impl<'a> IntoBuf for &'a [u8] {
59-
type Buf = io::Cursor<&'a [u8]>;
66+
type Buf = Cursor<&'a [u8]>;
6067

6168
fn into_buf(self) -> Self::Buf {
62-
io::Cursor::new(self)
69+
Cursor::new(self)
6370
}
6471
}
6572

6673
impl<'a> IntoBuf for &'a str {
67-
type Buf = io::Cursor<&'a [u8]>;
74+
type Buf = Cursor<&'a [u8]>;
6875

6976
fn into_buf(self) -> Self::Buf {
7077
self.as_bytes().into_buf()
7178
}
7279
}
7380

7481
impl IntoBuf for Vec<u8> {
75-
type Buf = io::Cursor<Vec<u8>>;
82+
type Buf = Cursor<Vec<u8>>;
7683

7784
fn into_buf(self) -> Self::Buf {
78-
io::Cursor::new(self)
85+
Cursor::new(self)
7986
}
8087
}
8188

8289
impl<'a> IntoBuf for &'a Vec<u8> {
83-
type Buf = io::Cursor<&'a [u8]>;
90+
type Buf = Cursor<&'a [u8]>;
8491

8592
fn into_buf(self) -> Self::Buf {
86-
io::Cursor::new(&self[..])
93+
Cursor::new(&self[..])
8794
}
8895
}
8996

9097
// Kind of annoying... but this impl is required to allow passing `&'static
9198
// [u8]` where for<'a> &'a T: IntoBuf is required.
9299
impl<'a> IntoBuf for &'a &'static [u8] {
93-
type Buf = io::Cursor<&'static [u8]>;
100+
type Buf = Cursor<&'static [u8]>;
94101

95102
fn into_buf(self) -> Self::Buf {
96-
io::Cursor::new(self)
103+
Cursor::new(self)
97104
}
98105
}
99106

100107
impl<'a> IntoBuf for &'a &'static str {
101-
type Buf = io::Cursor<&'static [u8]>;
108+
type Buf = Cursor<&'static [u8]>;
102109

103110
fn into_buf(self) -> Self::Buf {
104111
self.as_bytes().into_buf()
105112
}
106113
}
107114

108115
impl IntoBuf for String {
109-
type Buf = io::Cursor<Vec<u8>>;
116+
type Buf = Cursor<Vec<u8>>;
110117

111118
fn into_buf(self) -> Self::Buf {
112119
self.into_bytes().into_buf()
113120
}
114121
}
115122

116123
impl<'a> IntoBuf for &'a String {
117-
type Buf = io::Cursor<&'a [u8]>;
124+
type Buf = Cursor<&'a [u8]>;
118125

119126
fn into_buf(self) -> Self::Buf {
120127
self.as_bytes().into_buf()

src/buf/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ mod buf;
2020
mod buf_mut;
2121
mod from_buf;
2222
mod chain;
23+
#[cfg(not(feature = "use_std"))]
24+
mod cursor;
2325
mod into_buf;
2426
mod iter;
2527
mod reader;
@@ -30,6 +32,8 @@ pub use self::buf::Buf;
3032
pub use self::buf_mut::BufMut;
3133
pub use self::from_buf::FromBuf;
3234
pub use self::chain::Chain;
35+
#[cfg(not(feature = "use_std"))]
36+
pub use self::cursor::Cursor;
3337
pub use self::into_buf::IntoBuf;
3438
pub use self::iter::Iter;
3539
pub use self::reader::Reader;

src/buf/reader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use {Buf};
22

3+
#[cfg(feature = "use_std")]
34
use std::{cmp, io};
45

56
/// A `Buf` adapter which implements `io::Read` for the inner value.
@@ -78,6 +79,7 @@ impl<B: Buf> Reader<B> {
7879
}
7980
}
8081

82+
#[cfg(feature = "use_std")]
8183
impl<B: Buf + Sized> io::Read for Reader<B> {
8284
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> {
8385
let len = cmp::min(self.buf.remaining(), dst.len());

src/buf/take.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {Buf};
22

3-
use std::cmp;
3+
use core::cmp;
44

55
/// A `Buf` adapter which limits the bytes read from an underlying buffer.
66
///

src/buf/writer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use BufMut;
22

3+
#[cfg(feature = "use_std")]
34
use std::{cmp, io};
45

56
/// A `BufMut` adapter which implements `io::Write` for the inner value.
@@ -74,6 +75,7 @@ impl<B: BufMut> Writer<B> {
7475
}
7576
}
7677

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

0 commit comments

Comments
 (0)