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

io::{Read,Write} traits #12

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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