Skip to content

Commit

Permalink
rust: Fix no_std support (removes error-chain)
Browse files Browse the repository at this point in the history
The error-chain library does not support no_std:

rust-lang-deprecated/error-chain#138

This switches to a somewhat error-chain-like set of handwritten error
boilerplate, and makes sure to test in CI that the Rust crate compiles without
the "std" cargo feature.
  • Loading branch information
tarcieri committed Jun 3, 2017
1 parent 45293cf commit 9ccaefe
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 131 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ matrix:
- env: SUITE="rust"
language: rust
rust: nightly
- env: SUITE="rust" RUST_FEATURES="--no-default-features"
language: rust
rust: nightly
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
# ![zser][zser-logo-image]

[![Build Status][build-image]][build-link]
[![Code Climate][codeclimate-image]][codeclimate-link]
[![MIT licensed][license-image]][license-link]

[zser-logo-image]: https://raw.githubusercontent.com/zcred/logos/master/zser-logo-md.png
[build-image]: https://secure.travis-ci.org/zcred/zser.svg?branch=master
[build-link]: http://travis-ci.org/zcred/zser
[codeclimate-image]: https://codeclimate.com/github/zcred/zser.svg?branch=master
[codeclimate-link]: https://codeclimate.com/github/zcred/zser
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg
[license-link]: https://github.com/zcred/zser/blob/master/LICENSE.txt

Expand Down
1 change: 1 addition & 0 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ruby)
rust)
cd rust
cargo test
cargo build $RUST_FEATURES
;;
*)
echo "*** ERROR: Unknown test suite: '$SUITE'"
Expand Down
91 changes: 0 additions & 91 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ readme = "README.md"
categories = ["authentication", "cryptography", "encoding"]
keywords = ["authentication", "cryptography", "security", "serialization", "merkle"]

[dependencies]
error-chain = "0.10"

[dependencies.byteorder]
version = "0.5"
default-features = false
Expand Down
3 changes: 3 additions & 0 deletions rust/src/decoder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Decodes a zser message into `Zser::Value`

#[cfg(not(feature = "std"))]
use collections::vec::Vec;

use parser::Handler;
use value::{Map, Value};

Expand Down
120 changes: 97 additions & 23 deletions rust/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,110 @@
//! errors.rs: error types based on error-chain
//! errors.rs: error types used by this crate

#![allow(missing_docs)]
use core::fmt::{self, Debug, Display};
use core::result;

error_chain! {
types {
Error, ErrorKind, ResultExt, Result;
}
#[cfg(feature = "std")]
use std::error;

errors {
OversizedMessage(len: usize, limit: usize) {
description("message too long")
display("{}-byte message exceeds limit of {} bytes", len, limit)
}
#[cfg(not(feature = "std"))]
use collections::boxed::Box;

#[cfg(not(feature = "std"))]
use collections::string::String;

/// Errors which can occur when serializing or deserializing zser messages
pub struct Error {
err: Box<ErrorImpl>,
}

/// `Result` alias used by this crate
pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
struct ErrorImpl {
kind: ErrorKind,
byte_offset: Option<usize>,
}

/// Error variants encountered in this crate
#[derive(Debug)]
pub enum ErrorKind {
/// Message exceeds configured size limit
OversizedMessage(usize),

/// Message exceeds configured maximum for nested messages
MaxDepthExceeded(usize),

/// Expected more data in message
TruncatedMessage(String),

/// Message encoded with an unknown wiretype
UnknownWiretype(u64),

/// Unconsumed messages remaining in buffer
UnconsumedMessages(usize),
}

MaxDepthExceeded(max: usize) {
description("max nested message depth exceeded")
display("max nested message depth of {} bytes exceeded", max)
impl Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
ErrorKind::OversizedMessage(limit) => {
write!(f, "message exceeds limit of {} bytes", limit)
}
ErrorKind::MaxDepthExceeded(max) => {
write!(f, "max nested message depth of {} exceeded", max)
}
ErrorKind::TruncatedMessage(ref msg) => write!(f, "message truncated: {}", msg),
ErrorKind::UnknownWiretype(wiretype) => write!(f, "unknown wiretype: {}", wiretype),
ErrorKind::UnconsumedMessages(count) => {
write!(f, "unconsumed messages in buffer: {} messages", count)
}
}
}
}

TruncatedMessage(msg: String) {
description("message truncated")
display("message truncated: {}", msg)
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
match self.err.kind {
ErrorKind::OversizedMessage(_) => "message too long",
ErrorKind::MaxDepthExceeded(_) => "maximum number of nested messages exceeded",
ErrorKind::TruncatedMessage(_) => "message truncated",
ErrorKind::UnknownWiretype(_) => "unknown wiretype",
ErrorKind::UnconsumedMessages(_) => "unconsumed messages in buffer",
}
}
}

UnknownWiretype(wiretype: u64) {
description("unknown wiretype")
display("unknown wiretype: {}", wiretype)
impl From<ErrorKind> for Error {
fn from(ek: ErrorKind) -> Self {
Error {
err: Box::new(ErrorImpl {
kind: ek,
byte_offset: None,
}),
}
}
}

UnconsumedMessages(count: usize) {
description("unconsumed messages remaining in buffer")
display("unconsumed messages in buffer: {} messages", count)
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&*self.err, f)
}
}

impl Display for ErrorImpl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.byte_offset {
Some(offset) => write!(f, "{} at byte {}", self.kind, offset),
None => Display::fmt(&self.kind, f),
}

}
}

impl Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&*self.err, f)
}
}
7 changes: 4 additions & 3 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
#![cfg_attr(feature = "bench", feature(test))]

extern crate byteorder;
#[macro_use]
extern crate error_chain;

#[cfg(not(feature = "std"))]
extern crate collections;
#[macro_use] extern crate collections;

#[cfg(feature = "std")]
extern crate core;

#[cfg(all(feature = "bench", test))]
extern crate test;
Expand Down
2 changes: 1 addition & 1 deletion rust/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl<'m, H: Handler> Parser<'m, H> {
/// Parse the given zser message, invoking callbacks as necessary
pub fn parse(&mut self, message: &'m [u8]) -> Result<()> {
if message.len() > self.max_length {
return Err(ErrorKind::OversizedMessage(message.len(), self.max_length).into());
return Err(ErrorKind::OversizedMessage(self.max_length).into());
}

if self.remaining.len() >= self.max_depth {
Expand Down
17 changes: 13 additions & 4 deletions rust/src/value.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
//! The Value enum: a loosely typed way of representing zser messages.

#[cfg(not(feature = "std"))]
pub use collections::HashMap;

#[cfg(feature = "std")]
pub use std::collections::HashMap;

/// Integer ID -> Value mapping used to represent messages internally
#[cfg(not(feature = "std"))]
pub use collections::btree_map::BTreeMap;

#[cfg(not(feature = "std"))]
use collections::vec::Vec;

/// Integer ID -> Value mapping with `hashDoS`-resistant `HashMap` on std
#[cfg(feature = "std")]
pub type Map = HashMap<u64, Value>;

/// Integer ID -> Value mapping, using BTreeMap without std since we don't have HashMap
// TODO: hashDoS resistance in no_std environments
#[cfg(not(feature = "std"))]
pub type Map = BTreeMap<u64, Value>;

/// Represents any value that can occur in a zser message
#[derive(Debug, PartialEq)]
pub enum Value {
Expand Down
Loading

0 comments on commit 9ccaefe

Please sign in to comment.