Skip to content

Commit 75b69de

Browse files
committed
Add basic io::{Read, Write} traits modeled after futures-io
1 parent bd1e329 commit 75b69de

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

src/io/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
mod read;
2+
mod write;
3+
4+
pub use self::read::Read;
5+
pub use self::write::Write;

src/io/read.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use core::cmp;
2+
3+
use Result;
4+
5+
/// Non-blocking reader trait
6+
pub trait Read {
7+
/// An enumeration of possible errors
8+
///
9+
/// May be `!` (`never_type`) for infallible implementations
10+
type Error;
11+
12+
/// Pull some bytes from this source into the specified buffer, returning how many bytes were
13+
/// read.
14+
///
15+
/// If an object needs to block for a read it will return an `Err(nb::Error::WouldBlock)`
16+
/// return value.
17+
///
18+
/// If the return value of this method is `Ok(n)`, then it must be guaranteed that `0 <= n <=
19+
/// buf.len()`. The `n` value indicates that the buffer `buf` has been filled in with `n` bytes
20+
/// of data from this source. If `n == 0 && buf.len() > 0` then it can be assumed that this
21+
/// reader has run out of data and will not be able service any future read calls.
22+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
23+
}
24+
25+
impl<'a, R: ?Sized + Read> Read for &'a mut R {
26+
type Error = R::Error;
27+
28+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
29+
(**self).read(buf)
30+
}
31+
}
32+
33+
impl<'a> Read for &'a [u8] {
34+
type Error = !;
35+
36+
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
37+
let len = cmp::min(self.len(), buf.len());
38+
let (head, tail) = self.split_at(len);
39+
buf[..len].copy_from_slice(head);
40+
*self = tail;
41+
Ok(len)
42+
}
43+
}

src/io/write.rs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use core::{cmp, mem};
2+
3+
use Result;
4+
5+
/// Non-blocking writer trait
6+
pub trait Write {
7+
/// An enumeration of possible errors
8+
///
9+
/// May be `!` (`never_type`) for infallible implementations
10+
type Error;
11+
12+
/// Push some bytes into this source from the specified buffer, returning how many bytes were
13+
/// written.
14+
///
15+
/// If an object needs to block for a write it will return an `Err(nb::Error::WouldBlock)`
16+
/// return value.
17+
///
18+
/// If the return value of this method is `Ok(n)`, then it must be guaranteed that `0 <= n <=
19+
/// buf.len()`. The `n` value indicates that `n` bytes from the buffer `buf` have been written
20+
/// to this source. If `n == 0 && buf.len() > 0` then it can be assumed that this writer has
21+
/// run out of space and will not be able to service future writes.
22+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error>;
23+
24+
/// Attempt to flush the object, ensuring that any buffered data reach their destination.
25+
///
26+
/// On success, returns `Ok(())`.
27+
///
28+
/// If flushing cannot immediately complete, this method returns `Err(nb::Error::WouldBlock)`.
29+
fn flush(&mut self) -> Result<(), Self::Error>;
30+
31+
/// Attempt to close the object.
32+
///
33+
/// On success, returns `Ok(())`.
34+
///
35+
/// If closing cannot immediately complete, this method returns `Err(nb::Error::WouldBlock)`.
36+
fn close(&mut self) -> Result<(), Self::Error>;
37+
}
38+
39+
impl<'a, W: ?Sized + Write> Write for &'a mut W {
40+
type Error = W::Error;
41+
42+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
43+
(**self).write(buf)
44+
}
45+
46+
fn flush(&mut self) -> Result<(), Self::Error> {
47+
(**self).flush()
48+
}
49+
50+
fn close(&mut self) -> Result<(), Self::Error> {
51+
(**self).close()
52+
}
53+
}
54+
55+
impl<'a> Write for &'a mut [u8] {
56+
type Error = !;
57+
58+
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
59+
let len = cmp::min(self.len(), buf.len());
60+
let (head, tail) = mem::replace(self, &mut []).split_at_mut(len);
61+
head.copy_from_slice(&buf[..len]);
62+
*self = tail;
63+
Ok(len)
64+
}
65+
66+
fn flush(&mut self) -> Result<(), Self::Error> {
67+
Ok(())
68+
}
69+
70+
fn close(&mut self) -> Result<(), Self::Error> {
71+
Ok(())
72+
}
73+
}

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@
357357
#![no_std]
358358
#![deny(warnings)]
359359

360+
#![cfg_attr(feature = "unstable", feature(never_type))]
361+
362+
#[cfg(feature = "unstable")]
363+
pub mod io;
364+
360365
use core::fmt;
361366

362367
/// A non-blocking result

0 commit comments

Comments
 (0)