Skip to content

Commit

Permalink
Make io a subset of std::io
Browse files Browse the repository at this point in the history
So that when implementing a no-`std` logic we don't break the build when
some other dependency opts into `std` (causing API mismatch).
  • Loading branch information
Xanewok committed Jan 21, 2020
1 parent c52e80c commit 8acce36
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 17 deletions.
9 changes: 2 additions & 7 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ pub enum Category {
}

#[cfg_attr(feature = "cargo-clippy", allow(fallible_impl_from))]
#[cfg(feature = "std")]
impl From<Error> for io::Error {
/// Convert a `serde_json::Error` into an `io::Error`.
///
Expand Down Expand Up @@ -333,19 +332,15 @@ impl Display for ErrorCode {
}
}

#[cfg(feature = "std")]
impl error::Error for Error {
fn source(&self) -> Option<&(error::Error + 'static)> {
impl serde::de::StdError for Error {
fn source(&self) -> Option<&(serde::de::StdError + 'static)> {
match self.err.code {
ErrorCode::Io(ref err) => Some(err),
_ => None,
}
}
}

#[cfg(not(feature = "std"))]
impl serde::de::StdError for Error {}

impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&*self.err, f)
Expand Down
82 changes: 79 additions & 3 deletions src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,87 @@ use lib::*;

#[cfg(feature = "std")]
pub use std::io::ErrorKind;
#[cfg(not(feature = "std"))]
pub enum ErrorKind {
InvalidData,
WriteZero,
Other,
UnexpectedEof,
}

#[cfg(not(feature = "std"))]
impl ErrorKind {
#[inline]
fn as_str(&self) -> &'static str {
match self {
ErrorKind::InvalidData => "invalid data",
ErrorKind::WriteZero => "write zero",
ErrorKind::Other => "other os error",
ErrorKind::UnexpectedEof => "unexpected end of file",
}
}
}

#[cfg(feature = "std")]
pub use std::io::Error;
#[cfg(not(feature = "std"))]
pub type Error = &'static str;
pub struct Error {
repr: Repr,
}

#[cfg(not(feature = "std"))]
enum Repr {
Simple(ErrorKind),
Custom(ErrorKind, Box<dyn serde::de::StdError + Send + Sync>),
}

#[cfg(not(feature = "std"))]
impl Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.repr {
Repr::Custom(_, msg) => write!(fmt, "{}", msg),
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
}
}
}

#[cfg(not(feature = "std"))]
impl Debug for Error {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(self, fmt)
}
}

#[cfg(not(feature = "std"))]
impl serde::de::StdError for Error {}

#[cfg(not(feature = "std"))]
impl From<ErrorKind> for Error {
#[inline]
fn from(kind: ErrorKind) -> Error {
Error {
repr: Repr::Simple(kind),
}
}
}

#[cfg(not(feature = "std"))]
impl Error {
#[inline]
pub fn new<E>(kind: ErrorKind, error: E) -> Error
where
E: Into<Box<dyn serde::de::StdError + Send + Sync>>,
{
Error {
repr: Repr::Custom(kind, error.into()),
}
}
}

#[cfg(feature = "std")]
pub use std::io::Result;
#[cfg(not(feature = "std"))]
pub type Result<T> = core::result::Result<T, Error>;
pub type Result<T> = result::Result<T, Error>;

#[cfg(feature = "std")]
pub use std::io::Write;
Expand All @@ -35,7 +106,12 @@ pub trait Write {
fn write_all(&mut self, mut buf: &[u8]) -> Result<()> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => return Err("failed to write whole buffer"),
Ok(0) => {
return Err(Error::new(
ErrorKind::WriteZero,
"failed to write whole buffer",
))
}
Ok(n) => buf = &buf[n..],
Err(e) => return Err(e),
}
Expand Down
7 changes: 0 additions & 7 deletions src/value/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,18 +193,11 @@ struct WriterFormatter<'a, 'b: 'a> {

impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
#[cfg(feature = "std")]
fn io_error<E>(_: E) -> io::Error {
// Error value does not matter because fmt::Display impl below just
// maps it to fmt::Error
io::Error::new(io::ErrorKind::Other, "fmt error")
}

#[cfg(not(feature = "std"))]
fn io_error<E>(_: E) -> io::Error {
"fmt error"
}

let s = try!(str::from_utf8(buf).map_err(io_error));
try!(self.inner.write_str(s).map_err(io_error));
Ok(buf.len())
Expand Down

0 comments on commit 8acce36

Please sign in to comment.