Skip to content

Commit

Permalink
Add basic io::{Read, Write} traits modeled after futures-io
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo157 committed Mar 19, 2018
1 parent bd1e329 commit 75b69de
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod read;
mod write;

pub use self::read::Read;
pub use self::write::Write;
43 changes: 43 additions & 0 deletions src/io/read.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use core::cmp;

use Result;

/// Non-blocking reader trait
pub trait Read {
/// An enumeration of possible errors
///
/// May be `!` (`never_type`) for infallible implementations
type Error;

/// Pull some bytes from this source into the specified buffer, returning how many bytes were
/// read.
///
/// If an object needs to block for a read it will return an `Err(nb::Error::WouldBlock)`
/// return value.
///
/// If the return value of this method is `Ok(n)`, then it must be guaranteed that `0 <= n <=
/// buf.len()`. The `n` value indicates that the buffer `buf` has been filled in with `n` bytes
/// of data from this source. If `n == 0 && buf.len() > 0` then it can be assumed that this
/// reader has run out of data and will not be able service any future read calls.
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
}

impl<'a, R: ?Sized + Read> Read for &'a mut R {
type Error = R::Error;

fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
(**self).read(buf)
}
}

impl<'a> Read for &'a [u8] {
type Error = !;

fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
let len = cmp::min(self.len(), buf.len());
let (head, tail) = self.split_at(len);
buf[..len].copy_from_slice(head);
*self = tail;
Ok(len)
}
}
73 changes: 73 additions & 0 deletions src/io/write.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use core::{cmp, mem};

use Result;

/// Non-blocking writer trait
pub trait Write {
/// An enumeration of possible errors
///
/// May be `!` (`never_type`) for infallible implementations
type Error;

/// Push some bytes into this source from the specified buffer, returning how many bytes were
/// written.
///
/// If an object needs to block for a write it will return an `Err(nb::Error::WouldBlock)`
/// return value.
///
/// If the return value of this method is `Ok(n)`, then it must be guaranteed that `0 <= n <=
/// buf.len()`. The `n` value indicates that `n` bytes from the buffer `buf` have been written
/// to this source. If `n == 0 && buf.len() > 0` then it can be assumed that this writer has
/// run out of space and will not be able to service future writes.
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error>;

/// Attempt to flush the object, ensuring that any buffered data reach their destination.
///
/// On success, returns `Ok(())`.
///
/// If flushing cannot immediately complete, this method returns `Err(nb::Error::WouldBlock)`.
fn flush(&mut self) -> Result<(), Self::Error>;

/// Attempt to close the object.
///
/// On success, returns `Ok(())`.
///
/// If closing cannot immediately complete, this method returns `Err(nb::Error::WouldBlock)`.
fn close(&mut self) -> Result<(), Self::Error>;
}

impl<'a, W: ?Sized + Write> Write for &'a mut W {
type Error = W::Error;

fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
(**self).write(buf)
}

fn flush(&mut self) -> Result<(), Self::Error> {
(**self).flush()
}

fn close(&mut self) -> Result<(), Self::Error> {
(**self).close()
}
}

impl<'a> Write for &'a mut [u8] {
type Error = !;

fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
let len = cmp::min(self.len(), buf.len());
let (head, tail) = mem::replace(self, &mut []).split_at_mut(len);
head.copy_from_slice(&buf[..len]);
*self = tail;
Ok(len)
}

fn flush(&mut self) -> Result<(), Self::Error> {
Ok(())
}

fn close(&mut self) -> Result<(), Self::Error> {
Ok(())
}
}
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@
#![no_std]
#![deny(warnings)]

#![cfg_attr(feature = "unstable", feature(never_type))]

#[cfg(feature = "unstable")]
pub mod io;

use core::fmt;

/// A non-blocking result
Expand Down

0 comments on commit 75b69de

Please sign in to comment.