From 78ef89a4bae7695bc1e69cc6cace52eb57831619 Mon Sep 17 00:00:00 2001 From: Alex Helfet Date: Thu, 21 Dec 2017 05:08:54 +0000 Subject: [PATCH] Added default Cargo feature "use_std", no_std without it. `cargo test` still passes. `cargo build --no-default-features` builds, but no further tests done. --- Cargo.toml | 11 +++++++++-- src/error.rs | 43 ++++++++++++++++++++++++++++++------------- src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 77 insertions(+), 25 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7bf1d12..4592234 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,15 @@ cobs = "^0.1.2" error-chain = "^0.11.0" ref_slice = "^1.1.1" +[dependencies.core-io] +git = "https://github.com/QuiltOS/core-io" +rev = "f084f913011c9916d420b520ead3953a2ccb950e" + [features] -default_features = [] +default = ["use_std"] # Enable to print all data to stdout for testing. -trace = [] \ No newline at end of file +trace = [] + +# Use standard library, enabled by default; disable for no_std. +use_std = [] \ No newline at end of file diff --git a/src/error.rs b/src/error.rs index 5d72325..0b5f144 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,20 +1,37 @@ //! Representations of errors returned by this crate. +#[cfg(feature = "use_std")] use std::io; -error_chain! { - foreign_links { - Io(io::Error); - } +#[cfg(feature = "use_std")] +use std::result; +#[cfg(not(feature = "use_std"))] +use core::result; - errors { - CobsDecodeFailed { - description("COBS decode failed"), - display("COBS decode failed"), - } - EofDuringFrame { - description("end of file during a frame"), - display("end of file during a frame"), - } +pub type Result = result::Result; + +#[cfg_attr(feature = "use_std", derive(Debug))] +pub enum Error { + /// COBS decode failed + CobsDecodeFailed, + + /// End of file while reading a frame + EofDuringFrame, + + /// Forwarded io::Error. + #[cfg(feature = "use_std")] + Io(io::Error), + + /// Forwarded Io error. + /// + /// TODO: Store some extra value here. + #[cfg(not(feature = "use_std"))] + Io, +} + +#[cfg(feature = "use_std")] +impl From for Error { + fn from(e: io::Error) -> Error { + Error::Io(e) } } diff --git a/src/lib.rs b/src/lib.rs index 4c36f7f..d95f73b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,27 +16,40 @@ //! ## Cargo feature flags //! `trace`: Enable to print all data to stdout for testing. //! +//! `use_std`: Use standard library, enabled by default; disable for no_std. +//! //! ## TODO //! * Start frame with a zero as well, then we detect partial frames. //! * Add a length field to the beginning of the frame and a //! checksum to the end. Perhaps make them optional. -//! * Support no_std. #![deny(warnings)] #![feature(conservative_impl_trait)] +#![cfg_attr(not(feature = "use_std"), no_std)] + extern crate cobs; -#[macro_use] -extern crate error_chain; +#[cfg(not(feature = "use_std"))] +extern crate core_io; + extern crate ref_slice; +#[cfg(feature = "use_std")] pub mod channel; pub mod error; -use error::{Error, ErrorKind, Result}; +#[allow(unused_imports)] +use error::{Error, Result}; + +#[cfg(feature = "use_std")] use ref_slice::ref_slice_mut; + +#[cfg(feature = "use_std")] use std::io::{self, Read, Write}; +#[cfg(not(feature = "use_std"))] +use core_io::{Read, Write}; + const FRAME_END: u8 = 0; /// Sends frames over an underlying `io::Write` instance. @@ -57,13 +70,27 @@ impl Sender { #[cfg(feature = "trace")] { println!("framed: Sending code = {:?}", code); } - self.w.write(&code)?; + + #[cfg(feature = "use_std")] { + self.w.write(&code)?; + } + + #[cfg(not(feature = "use_std"))] { + self.w.write(&code) + .map_err(|_| Error::Io)?; + } + Ok(()) } } /// Receives frames from an underlying `io::Read` instance. +/// +/// TODO: Add a recv() variant suitable for no_std use, e.g. one that +/// takes a `&mut [u8]`. pub struct Receiver { + + #[cfg_attr(not(feature = "use_std"), allow(dead_code))] /// The underlying reader r: R, } @@ -75,6 +102,7 @@ impl Receiver { } } + #[cfg(feature = "use_std")] pub fn recv(&mut self) -> Result> { let mut next_frame = Vec::new(); @@ -86,9 +114,9 @@ impl Receiver { } match res { Err(ref e) if e.kind() == io::ErrorKind::UnexpectedEof => - return Err(Error::from(ErrorKind::EofDuringFrame)), + return Err(Error::EofDuringFrame), Ok(0) => - return Err(Error::from(ErrorKind::EofDuringFrame)), + return Err(Error::EofDuringFrame), Err(e) => return Err(Error::from(e)), Ok(_) => (), }; @@ -105,14 +133,14 @@ impl Receiver { assert!(b == FRAME_END); cobs::decode_vec(&next_frame) - .map_err(|_| Error::from(ErrorKind::CobsDecodeFailed)) + .map_err(|_| Error::CobsDecodeFailed) } } #[cfg(test)] mod tests { use channel::Channel; - use error::{Error, ErrorKind}; + use error::Error; use std::io::{Read, Write}; use super::{Receiver, Sender}; @@ -165,7 +193,7 @@ mod tests { fn empty_input() { let (mut _tx, mut rx) = pair(); match rx.recv() { - Err(Error(ErrorKind::EofDuringFrame, _)) => (), + Err(Error::EofDuringFrame) => (), e @ _ => panic!("Bad value: {:?}", e) } }