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

Maintenance and perf improvements #17

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
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
54 changes: 54 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: serde-rlp CI

on: [pull_request]

env:
RUSTFLAGS: -D warnings
RUST_BACKTRACE: 1

jobs:
test_and_build_stable:
name: Test and Stable build suite
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Rust components
run: |
rustup set profile minimal
rustup default stable
- name: Run test suite
run: |
cargo test
cargo test --release
cargo build

rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Acquire the most recent nightly with a rustfmt component
- name: Install most recent Rustfmt
run: |
rustup set profile minimal
rustup default "nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/rustfmt)"
rustup component add rustfmt
- name: Run `cargo fmt`
run: |
cargo fmt -- --check

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Acquire the most recent nightly with a clippy component
- name: Install most recent Clippy
run: |
rustup set profile minimal
rustup default "nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/clippy)"
rustup component add clippy
- name: Run `cargo clippy`
run: |
cargo clippy --all --all-targets --no-default-features -- -D clippy::all
cargo clippy --all --all-targets --all-features -- -D clippy::all
47 changes: 0 additions & 47 deletions .travis.yml

This file was deleted.

10 changes: 4 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[package]
name = "serde-rlp"
edition = "2021"
version = "0.1.4"
authors = ["Michał Papierski <[email protected]>"]
include = [
Expand All @@ -14,11 +15,8 @@ license-file = "LICENSE"
travis-ci = { repository = "althea-mesh/serde-rlp", branch = "master" }

[dependencies]
byteorder = "1.2"
num = "0.2"
error = "0.1"
serde = "1.0.0"
serde = "1"

[dev-dependencies]
serde_derive = "1.0.0"
serde_bytes = "0.10"
serde_bytes = "0.11"
serde_derive = "1"
66 changes: 35 additions & 31 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::ops::{AddAssign, MulAssign, Neg};

use serde::de::{self, Deserialize, DeserializeSeed, SeqAccess, Visitor};

use rlp::{self, ExpectedType};
use crate::rlp::{self, ExpectedType};

use error::{Error, Result};
use crate::error::{Error, Result};
use std::str;

pub struct Deserializer<'de> {
Expand All @@ -17,7 +17,7 @@ pub struct Deserializer<'de> {
impl<'de> Deserializer<'de> {
pub fn from_bytes(input: &'de [u8]) -> Self {
Deserializer {
input: input,
input,
stack: VecDeque::new(),
}
}
Expand All @@ -29,7 +29,7 @@ where
{
let mut deserializer = Deserializer::from_bytes(s);
let t = T::deserialize(&mut deserializer)?;
if deserializer.input.len() == 0 {
if deserializer.input.is_empty() {
Ok(t)
} else {
Err(Error::TrailingBytes)
Expand Down Expand Up @@ -58,7 +58,7 @@ impl<'de> Deserializer<'de> {
}

fn parse_string(&mut self) -> Result<&'de str> {
let res = rlp::decode_length(&self.input)?;
let res = rlp::decode_length(self.input)?;
if res.expected_type == ExpectedType::StringType {
let s = str::from_utf8(&self.input[res.offset..res.offset + res.length])
.map_err(|_| Error::InvalidString)?;
Expand All @@ -70,7 +70,7 @@ impl<'de> Deserializer<'de> {
}

fn parse_bytes(&mut self) -> Result<&'de [u8]> {
let res = rlp::decode_length(&self.input)?;
let res = rlp::decode_length(self.input)?;
if res.expected_type == ExpectedType::StringType {
let s = &self.input[res.offset..res.offset + res.length];
self.input = &self.input[res.offset + res.length..];
Expand Down Expand Up @@ -243,12 +243,12 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
let res = rlp::decode_length(&self.input)?;
let res = rlp::decode_length(self.input)?;
if res.expected_type == ExpectedType::ListType {
let nested = &self.input[res.offset..res.offset + res.length];
self.stack.push_front(&self.input);
self.stack.push_front(self.input);
self.input = nested;
let value = visitor.visit_seq(RlpListDecoder::new(&mut self))?;
let value = visitor.visit_seq(RlpListDecoder::new(self))?;
self.input = self.stack.pop_front().unwrap();
self.input = &self.input[res.offset + res.length..];
Ok(value)
Expand Down Expand Up @@ -344,11 +344,11 @@ impl<'de, 'a> SeqAccess<'de> for RlpListDecoder<'a, 'de> {
where
T: DeserializeSeed<'de>,
{
if self.de.input.len() == 0 {
if self.de.input.is_empty() {
// No more elements
return Ok(None);
}
match rlp::decode_length(&self.de.input)?.expected_type {
match rlp::decode_length(self.de.input)?.expected_type {
ExpectedType::StringType => {
let result = seed.deserialize(&mut *self.de);
result.map(Some)
Expand All @@ -366,21 +366,21 @@ impl<'de, 'a> SeqAccess<'de> for RlpListDecoder<'a, 'de> {

#[test]
fn deserialize_short_string() {
let foo: String = from_bytes(&[0x61u8]).unwrap();
assert_eq!(foo, "a");
let x: String = from_bytes(&[0x61u8]).unwrap();
assert_eq!(x, "a");
}

#[test]
fn deserialize_longer_string() {
let foo: String = from_bytes(&[0x83, 0x61, 0x62, 0x63]).unwrap();
assert_eq!(foo, "abc");
let x: String = from_bytes(&[0x83, 0x61, 0x62, 0x63]).unwrap();
assert_eq!(x, "abc");
}

#[test]
fn deserialize_short_array() {
let foo: Vec<String> =
let x: Vec<String> =
from_bytes(&[0xc8, 0x83, 0x61, 0x62, 0x63, 0x83, 0x64, 0x65, 0x66]).unwrap();
assert_eq!(foo, vec!["abc", "def"]);
assert_eq!(x, vec!["abc", "def"]);
}

#[test]
Expand All @@ -393,17 +393,17 @@ fn deserialize_short_array_into_tuple() {

#[test]
fn deserialize_nested_sequence_of_string_seq() {
let foo: Vec<Vec<String>> =
let x: Vec<Vec<String>> =
from_bytes(&[0xc9, 0xc8, 0x83, 0x61, 0x62, 0x63, 0x83, 0x64, 0x65, 0x66]).unwrap();
assert_eq!(foo, vec![vec!["abc", "def"]]);
assert_eq!(x, vec![vec!["abc", "def"]]);
}

#[test]
fn deserialize_set_representation_of_three() {
//
let foo = from_bytes(&[0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]);
let x = from_bytes(&[0xc7, 0xc0, 0xc1, 0xc0, 0xc3, 0xc0, 0xc1, 0xc0]);
assert_eq!(
foo,
x,
Ok(vec![
vec![],
vec![vec![]],
Expand All @@ -414,10 +414,11 @@ fn deserialize_set_representation_of_three() {

#[test]
fn deserialize_three_levels() {
let foo: Vec<Vec<Vec<String>>> = from_bytes(&[
let x: Vec<Vec<Vec<String>>> = from_bytes(&[
0xca, 0xc9, 0xc8, 0x83, 0x61, 0x62, 0x63, 0x83, 0x64, 0x65, 0x66,
]).unwrap();
assert_eq!(foo, [[["abc", "def"]]]);
])
.unwrap();
assert_eq!(x, [[["abc", "def"]]]);
}

#[test]
Expand All @@ -426,14 +427,16 @@ fn simple_invalid() {
let _foo: String = from_bytes(&[0x83, 0x61, 0x62, 0x63, /* excess */ 0xff]).unwrap();
}

#[cfg(test)]
fn get_bytes(b: &str) -> Option<Vec<u8>> {
b.as_bytes()
.chunks(2)
.map(|ch| {
str::from_utf8(&ch)
str::from_utf8(ch)
.ok()
.and_then(|res| u8::from_str_radix(&res, 16).ok())
}).collect()
.and_then(|res| u8::from_str_radix(res, 16).ok())
})
.collect()
}

#[test]
Expand All @@ -442,19 +445,20 @@ fn invalid_complex() {
let data = get_bytes("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c00804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3").unwrap();

assert_eq!(
from_bytes::<Vec<Bytes>>(&data).unwrap_err(),
from_bytes::<Vec<&Bytes>>(&data).unwrap_err(),
Error::WrongPrefix
);
}

#[test]
fn lorem_ipsum() {
let data: String = from_bytes(&vec![
let data: String = from_bytes(&[
0xb8, 0x38, 0x4c, 0x6f, 0x72, 0x65, 0x6d, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6d, 0x20, 0x64,
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6d, 0x65, 0x74, 0x2c, 0x20,
0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69,
0x70, 0x69, 0x73, 0x69, 0x63, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6c, 0x69, 0x74,
]).unwrap();
])
.unwrap();
assert_eq!(
data,
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
Expand All @@ -465,7 +469,7 @@ fn lorem_ipsum() {
fn unsigned_eth_transaction() {
use serde_bytes::Bytes;
let data = get_bytes("f83f8085e8d4a510008227108080af6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f2808080").unwrap();
let decoded: Vec<Bytes> = from_bytes(&data).unwrap();
let decoded: Vec<&Bytes> = from_bytes(&data).unwrap();

assert_eq!(
decoded,
Expand Down
13 changes: 7 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std;
use std::fmt::{self, Display};

use serde::{de, ser};

pub type Result<T> = std::result::Result<T, Error>;

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Error {
Message(String),
TrailingBytes,
Expand All @@ -39,13 +38,15 @@ impl de::Error for Error {
}

impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(std::error::Error::description(self))
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}

impl std::error::Error for Error {
fn description(&self) -> &str {
impl std::error::Error for Error {}

impl Error {
pub fn as_str(&self) -> &str {
match *self {
Error::Message(ref msg) => msg,
Error::TrailingBytes => "Trailing bytes found at the end of input",
Expand Down
7 changes: 0 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate byteorder;
extern crate num;
extern crate serde;

pub mod de;
mod error;
mod rlp;
pub mod ser;

#[cfg(test)]
extern crate serde_bytes;
Loading