{
}
}
+/// Implement notion of 0 allocation size for some type(s).
+///
+/// if used for generics, by default it will require that generaic arguments
+/// should implement `MallocSizeOf`. This can be avoided with passing "any: "
+/// in front of type list.
+///
+/// ```rust
+/// use parity_util_mem::{malloc_size, malloc_size_of_is_0};
+///
+/// struct Data {
+/// phantom: std::marker::PhantomData
,
+/// }
+///
+/// malloc_size_of_is_0!(any: Data
);
+///
+/// // MallocSizeOf is NOT implemented for [u8; 333]
+/// assert_eq!(malloc_size(&Data::<[u8; 333]> { phantom: std::marker::PhantomData }), 0);
+/// ```
+///
+/// and when no "any: "
+///
+/// ```rust
+/// use parity_util_mem::{malloc_size, malloc_size_of_is_0};
+///
+/// struct Data(pub T);
+///
+/// // generic argument (`T`) must be `impl MallocSizeOf`
+/// malloc_size_of_is_0!(Data);
+///
+/// assert_eq!(malloc_size(&Data(0u8)), 0);
+/// ```
#[macro_export]
macro_rules! malloc_size_of_is_0(
- ($($ty:ty),+) => (
- $(
- impl $crate::MallocSizeOf for $ty {
- #[inline(always)]
- fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
- 0
- }
- }
- )+
- );
- ($($ty:ident<$($gen:ident),+>),+) => (
- $(
- impl<$($gen: $crate::MallocSizeOf),+> $crate::MallocSizeOf for $ty<$($gen),+> {
- #[inline(always)]
- fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
- 0
- }
- }
- )+
- );
+ ($($ty:ty),+) => (
+ $(
+ impl $crate::MallocSizeOf for $ty {
+ #[inline(always)]
+ fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
+ 0
+ }
+ }
+ )+
+ );
+ (any: $($ty:ident<$($gen:ident),+>),+) => (
+ $(
+ impl<$($gen),+> $crate::MallocSizeOf for $ty<$($gen),+> {
+ #[inline(always)]
+ fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
+ 0
+ }
+ }
+ )+
+ );
+ ($($ty:ident<$($gen:ident),+>),+) => (
+ $(
+ impl<$($gen: $crate::MallocSizeOf),+> $crate::MallocSizeOf for $ty<$($gen),+> {
+ #[inline(always)]
+ fn size_of(&self, _: &mut $crate::MallocSizeOfOps) -> usize {
+ 0
+ }
+ }
+ )+
+ );
);
malloc_size_of_is_0!(bool, char, str);
@@ -676,6 +742,7 @@ malloc_size_of_is_0!(std::time::Duration);
mod tests {
use crate::{allocators::new_malloc_size_ops, MallocSizeOf, MallocSizeOfOps};
use smallvec::SmallVec;
+ use std::collections::BTreeSet;
use std::mem;
impl_smallvec!(3);
@@ -727,4 +794,26 @@ mod tests {
let expected_min_allocs = mem::size_of::() * 4 + "ÖWL".len() + "COW".len() + "PIG".len() + "DUCK".len();
assert!(v.size_of(&mut ops) >= expected_min_allocs);
}
+
+ #[test]
+ fn btree_set() {
+ let mut set = BTreeSet::new();
+ for t in 0..100 {
+ set.insert(vec![t]);
+ }
+ // ~36 per value
+ assert!(crate::malloc_size(&set) > 3000);
+ }
+
+ #[test]
+ fn special_malloc_size_of_0() {
+ struct Data {
+ phantom: std::marker::PhantomData
,
+ }
+
+ malloc_size_of_is_0!(any: Data
);
+
+ // MallocSizeOf is not implemented for [u8; 333]
+ assert_eq!(crate::malloc_size(&Data::<[u8; 333]> { phantom: std::marker::PhantomData }), 0);
+ }
}
diff --git a/parity-util-mem/src/primitives_impls.rs b/parity-util-mem/src/primitives_impls.rs
new file mode 100644
index 000000000..cf98bc211
--- /dev/null
+++ b/parity-util-mem/src/primitives_impls.rs
@@ -0,0 +1,26 @@
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Implementation of `MallocSize` primitive types.
+
+use primitive_types::{H160, H256, H512, U128, U256, U512};
+
+malloc_size_of_is_0!(U128, U256, U512, H160, H256, H512);
+
+#[cfg(test)]
+mod tests {
+
+ use primitive_types::H256;
+
+ #[test]
+ fn smoky() {
+ let v = vec![H256::zero(), H256::zero()];
+
+ assert!(crate::MallocSizeOfExt::malloc_size_of(&v) >= 64);
+ }
+}
diff --git a/parity-util-mem/src/sizeof.rs b/parity-util-mem/src/sizeof.rs
index ef63e1000..3d60913e4 100644
--- a/parity-util-mem/src/sizeof.rs
+++ b/parity-util-mem/src/sizeof.rs
@@ -1,18 +1,10 @@
-// Copyright 2015-2019 Parity Technologies (UK) Ltd.
-// This file is part of Parity.
-
-// Parity is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Parity is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Parity. If not, see .
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
//! Estimation for heapsize calculation. Usable to replace call to allocator method (for some
//! allocators or simply because we just need a deterministic cunsumption measurement).
diff --git a/parity-util-mem/tests/derive.rs b/parity-util-mem/tests/derive.rs
index 87f8c9f50..4fb5f7328 100644
--- a/parity-util-mem/tests/derive.rs
+++ b/parity-util-mem/tests/derive.rs
@@ -1,18 +1,10 @@
-// Copyright 2015-2019 Parity Technologies (UK) Ltd.
-// This file is part of Parity.
-
-// Parity is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Parity is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Parity. If not, see .
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
#![cfg(feature = "std")]
diff --git a/plain_hasher/CHANGELOG.md b/plain_hasher/CHANGELOG.md
index a4bd19586..c3f142cfd 100644
--- a/plain_hasher/CHANGELOG.md
+++ b/plain_hasher/CHANGELOG.md
@@ -1,12 +1,15 @@
# Changelog
-The format is based on [Keep a Changelog].
+The format is based on [Keep a Changelog].
[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
## [Unreleased]
+## [0.2.3] - 2020-03-16
+- License changed from MIT to dual MIT/Apache2. [#342](https://github.com/paritytech/parity-common/pull/342)
+
## [0.2.2] - 2019-10-24
-- Migrated to 2018 edition (https://github.com/paritytech/parity-common/pull/213)
+- Migrated to 2018 edition. [#213](https://github.com/paritytech/parity-common/pull/213)
### Dependencies
-- Updated dependencies (https://github.com/paritytech/parity-common/pull/239)
+- Updated dependencies. [#239](https://github.com/paritytech/parity-common/pull/239)
diff --git a/plain_hasher/Cargo.toml b/plain_hasher/Cargo.toml
index 2a7f94989..bb5a1668d 100644
--- a/plain_hasher/Cargo.toml
+++ b/plain_hasher/Cargo.toml
@@ -1,9 +1,9 @@
[package]
name = "plain_hasher"
description = "Hasher for 32-byte keys."
-version = "0.2.2"
+version = "0.2.3"
authors = ["Parity Technologies "]
-license = "MIT"
+license = "MIT OR Apache-2.0"
keywords = ["hash", "hasher"]
homepage = "https://github.com/paritytech/parity-common"
categories = ["no-std"]
diff --git a/plain_hasher/benches/bench.rs b/plain_hasher/benches/bench.rs
index 4ba53bb1a..e14d9d7d7 100644
--- a/plain_hasher/benches/bench.rs
+++ b/plain_hasher/benches/bench.rs
@@ -1,18 +1,10 @@
-// Copyright 2015-2018 Parity Technologies (UK) Ltd.
-// This file is part of Parity.
-
-// Parity is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Parity is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Parity. If not, see .
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
diff --git a/plain_hasher/src/lib.rs b/plain_hasher/src/lib.rs
index 3665995d4..4da4a508b 100644
--- a/plain_hasher/src/lib.rs
+++ b/plain_hasher/src/lib.rs
@@ -1,18 +1,10 @@
-// Copyright 2015-2018 Parity Technologies (UK) Ltd.
-// This file is part of Parity.
-
-// Parity is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Parity is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Parity. If not, see .
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
#![cfg_attr(not(feature = "std"), no_std)]
diff --git a/primitive-types/CHANGELOG.md b/primitive-types/CHANGELOG.md
index 12b958c30..018d16eda 100644
--- a/primitive-types/CHANGELOG.md
+++ b/primitive-types/CHANGELOG.md
@@ -5,10 +5,17 @@ The format is based on [Keep a Changelog].
[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
## [Unreleased]
+- Added `no_std` support for `serde` feature. [#385](https://github.com/paritytech/parity-common/pull/385)
+
+## [0.7.1] - 2020-04-27
+- Added `arbitrary` feature. [#378](https://github.com/paritytech/parity-common/pull/378)
+
+## [0.7.0] - 2020-03-16
+- Removed `libc` feature. [#317](https://github.com/paritytech/parity-common/pull/317)
## [0.6.2] - 2019-01-03
- Expose to_hex and from_hex from impl-serde. [#302](https://github.com/paritytech/parity-common/pull/302)
## [0.6.1] - 2019-10-24
### Dependencies
-- Updated dependencies (https://github.com/paritytech/parity-common/pull/239)
+- Updated dependencies. [#239](https://github.com/paritytech/parity-common/pull/239)
diff --git a/primitive-types/Cargo.toml b/primitive-types/Cargo.toml
index 36c0bc1c3..7a4908b13 100644
--- a/primitive-types/Cargo.toml
+++ b/primitive-types/Cargo.toml
@@ -1,15 +1,15 @@
[package]
name = "primitive-types"
-version = "0.6.2"
+version = "0.7.1"
authors = ["Parity Technologies "]
-license = "Apache-2.0/MIT"
+license = "MIT OR Apache-2.0"
homepage = "https://github.com/paritytech/parity-common"
description = "Primitive types shared by Ethereum and Substrate"
edition = "2018"
[dependencies]
-fixed-hash = { version = "0.5", path = "../fixed-hash", default-features = false }
-uint = { version = "0.8.1", path = "../uint", default-features = false }
+fixed-hash = { version = "0.6", path = "../fixed-hash", default-features = false }
+uint = { version = "0.8.3", path = "../uint", default-features = false }
impl-serde = { version = "0.3.0", path = "impls/serde", default-features = false, optional = true }
impl-codec = { version = "0.4.1", path = "impls/codec", default-features = false, optional = true }
impl-rlp = { version = "0.2", path = "impls/rlp", default-features = false, optional = true }
@@ -20,11 +20,12 @@ scale-info = { git = "https://github.com/paritytech/scale-info", default-feature
default = ["std"]
std = ["uint/std", "fixed-hash/std", "impl-codec/std"]
byteorder = ["fixed-hash/byteorder"]
-libc = ["fixed-hash/libc"]
rustc-hex = ["fixed-hash/rustc-hex"]
-serde = ["std", "impl-serde"]
+serde = ["std", "impl-serde", "impl-serde/std"]
+serde_no_std = ["impl-serde"]
codec = ["impl-codec"]
rlp = ["impl-rlp"]
+arbitrary = ["fixed-hash/arbitrary", "uint/arbitrary"]
[[test]]
name = "scale_info"
diff --git a/primitive-types/impls/codec/Cargo.toml b/primitive-types/impls/codec/Cargo.toml
index 12fda74f2..df837fd01 100644
--- a/primitive-types/impls/codec/Cargo.toml
+++ b/primitive-types/impls/codec/Cargo.toml
@@ -2,7 +2,7 @@
name = "impl-codec"
version = "0.4.2"
authors = ["Parity Technologies "]
-license = "Apache-2.0/MIT"
+license = "MIT OR Apache-2.0"
homepage = "https://github.com/paritytech/parity-common"
description = "Parity Codec serialization support for uint and fixed hash."
edition = "2018"
diff --git a/primitive-types/impls/codec/src/lib.rs b/primitive-types/impls/codec/src/lib.rs
index 9e5714ce0..1a4f2e252 100644
--- a/primitive-types/impls/codec/src/lib.rs
+++ b/primitive-types/impls/codec/src/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2018 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/primitive-types/impls/rlp/Cargo.toml b/primitive-types/impls/rlp/Cargo.toml
index 62e957c85..fbc12c7fb 100644
--- a/primitive-types/impls/rlp/Cargo.toml
+++ b/primitive-types/impls/rlp/Cargo.toml
@@ -2,7 +2,7 @@
name = "impl-rlp"
version = "0.2.1"
authors = ["Parity Technologies "]
-license = "Apache-2.0/MIT"
+license = "MIT OR Apache-2.0"
homepage = "https://github.com/paritytech/parity-common"
description = "RLP serialization support for uint and fixed hash."
edition = "2018"
diff --git a/primitive-types/impls/rlp/src/lib.rs b/primitive-types/impls/rlp/src/lib.rs
index 16a711370..e542c6e6e 100644
--- a/primitive-types/impls/rlp/src/lib.rs
+++ b/primitive-types/impls/rlp/src/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2018 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/primitive-types/impls/serde/CHANGELOG.md b/primitive-types/impls/serde/CHANGELOG.md
index a63cfb2f1..e58aeb12c 100644
--- a/primitive-types/impls/serde/CHANGELOG.md
+++ b/primitive-types/impls/serde/CHANGELOG.md
@@ -8,4 +8,4 @@ The format is based on [Keep a Changelog].
## [0.2.3] - 2019-10-29
### Fixed
-- Fixed a bug in empty slice serialization (https://github.com/paritytech/parity-common/pull/253)
+- Fixed a bug in empty slice serialization. [#253](https://github.com/paritytech/parity-common/pull/253)
diff --git a/primitive-types/impls/serde/Cargo.toml b/primitive-types/impls/serde/Cargo.toml
index a57ada2a2..b89051f75 100644
--- a/primitive-types/impls/serde/Cargo.toml
+++ b/primitive-types/impls/serde/Cargo.toml
@@ -3,18 +3,22 @@ name = "impl-serde"
version = "0.3.0"
authors = ["Parity Technologies "]
edition = "2018"
-license = "Apache-2.0/MIT"
+license = "MIT OR Apache-2.0"
homepage = "https://github.com/paritytech/parity-common"
description = "Serde serialization support for uint and fixed hash."
+[features]
+default = ["std"]
+std = ["serde/std"]
+
[dependencies]
-serde = "1.0.101"
+serde = { version = "1.0.101", default-features = false, features = ["alloc"] }
[dev-dependencies]
criterion = "0.3.0"
serde_derive = "1.0.101"
serde_json = "1.0.41"
-uint = "0.8.1"
+uint = { version = "0.8.3", path = "../../../uint" }
[[bench]]
name = "impl_serde"
diff --git a/primitive-types/impls/serde/benches/impl_serde.rs b/primitive-types/impls/serde/benches/impl_serde.rs
index d19a97fda..c7a1efea8 100644
--- a/primitive-types/impls/serde/benches/impl_serde.rs
+++ b/primitive-types/impls/serde/benches/impl_serde.rs
@@ -1,4 +1,4 @@
-// Copyright 2019 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/primitive-types/impls/serde/benches/input.rs b/primitive-types/impls/serde/benches/input.rs
index 00d5efdc5..5673f1f52 100644
--- a/primitive-types/impls/serde/benches/input.rs
+++ b/primitive-types/impls/serde/benches/input.rs
@@ -1,3 +1,11 @@
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
/// Hexdecimal string 64 chars (32 bytes)
pub const HEX_64_CHARS: &str = "\"0x6402541b4e3c2ab65306aec48fce5adedc60e3ac465c3d7036c731e0b2e49209\"";
diff --git a/primitive-types/impls/serde/src/lib.rs b/primitive-types/impls/serde/src/lib.rs
index 661ff7c0e..63fe535cb 100644
--- a/primitive-types/impls/serde/src/lib.rs
+++ b/primitive-types/impls/serde/src/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2019 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
@@ -8,6 +8,14 @@
//! Serde serialization support for uint and fixed hash.
+#![no_std]
+
+#[macro_use]
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
#[doc(hidden)]
pub use serde;
diff --git a/primitive-types/impls/serde/src/serialize.rs b/primitive-types/impls/serde/src/serialize.rs
index 01e85c036..90e42e2a6 100644
--- a/primitive-types/impls/serde/src/serialize.rs
+++ b/primitive-types/impls/serde/src/serialize.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2019 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
@@ -6,8 +6,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::fmt;
+use core::result::Result;
use serde::{de, Deserializer, Serializer};
-use std::fmt;
static CHARS: &[u8] = b"0123456789abcdef";
@@ -58,7 +61,7 @@ fn to_hex_raw<'a>(v: &'a mut [u8], bytes: &[u8], skip_leading_zero: bool) -> &'a
}
// SAFETY: all characters come either from CHARS or "0x", therefore valid UTF8
- unsafe { std::str::from_utf8_unchecked(&v[0..idx]) }
+ unsafe { core::str::from_utf8_unchecked(&v[0..idx]) }
}
/// Decoding bytes from hex string error.
@@ -75,6 +78,7 @@ pub enum FromHexError {
},
}
+#[cfg(feature = "std")]
impl std::error::Error for FromHexError {}
impl fmt::Display for FromHexError {
@@ -272,9 +276,7 @@ where
#[cfg(test)]
mod tests {
use super::*;
- extern crate serde_derive;
-
- use self::serde_derive::{Deserialize, Serialize};
+ use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Bytes(#[serde(with = "super")] Vec);
diff --git a/primitive-types/src/lib.rs b/primitive-types/src/lib.rs
index 2657bbf3e..efbb9adba 100644
--- a/primitive-types/src/lib.rs
+++ b/primitive-types/src/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2018 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/rlp-derive/CHANGELOG.md b/rlp-derive/CHANGELOG.md
new file mode 100644
index 000000000..d7b344b76
--- /dev/null
+++ b/rlp-derive/CHANGELOG.md
@@ -0,0 +1,10 @@
+# Changelog
+
+The format is based on [Keep a Changelog].
+
+[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
+
+## [Unreleased]
+
+## [0.1.0] - 2020-02-13
+- Extracted from parity-ethereum repo. [#343](https://github.com/paritytech/parity-common/pull/343)
diff --git a/rlp-derive/Cargo.toml b/rlp-derive/Cargo.toml
new file mode 100644
index 000000000..5059d6d02
--- /dev/null
+++ b/rlp-derive/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "rlp-derive"
+version = "0.1.0"
+authors = ["Parity Technologies "]
+license = "MIT OR Apache-2.0"
+description = "Derive macro for #[derive(RlpEncodable, RlpDecodable)]"
+homepage = "http://parity.io"
+edition = "2018"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+syn = "1.0.14"
+quote = "1.0.2"
+proc-macro2 = "1.0.8"
+
+[dev-dependencies]
+rlp = "0.4.4"
diff --git a/rlp-derive/src/de.rs b/rlp-derive/src/de.rs
new file mode 100644
index 000000000..730c39270
--- /dev/null
+++ b/rlp-derive/src/de.rs
@@ -0,0 +1,163 @@
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::TokenStream;
+use quote::quote;
+
+struct ParseQuotes {
+ single: TokenStream,
+ list: TokenStream,
+ takes_index: bool,
+}
+
+fn decodable_parse_quotes() -> ParseQuotes {
+ ParseQuotes { single: quote! { rlp.val_at }, list: quote! { rlp.list_at }, takes_index: true }
+}
+
+fn decodable_wrapper_parse_quotes() -> ParseQuotes {
+ ParseQuotes { single: quote! { rlp.as_val }, list: quote! { rlp.as_list }, takes_index: false }
+}
+
+pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream {
+ let body = if let syn::Data::Struct(s) = &ast.data {
+ s
+ } else {
+ panic!("#[derive(RlpDecodable)] is only defined for structs.");
+ };
+
+ let mut default_attribute_encountered = false;
+ let stmts: Vec<_> = body
+ .fields
+ .iter()
+ .enumerate()
+ .map(|(i, field)| decodable_field(i, field, decodable_parse_quotes(), &mut default_attribute_encountered))
+ .collect();
+ let name = &ast.ident;
+
+ let impl_block = quote! {
+ impl rlp::Decodable for #name {
+ fn decode(rlp: &rlp::Rlp) -> Result {
+ let result = #name {
+ #(#stmts)*
+ };
+
+ Ok(result)
+ }
+ }
+ };
+
+ quote! {
+ const _: () = {
+ extern crate rlp;
+ #impl_block
+ };
+ }
+}
+
+pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
+ let body = if let syn::Data::Struct(s) = &ast.data {
+ s
+ } else {
+ panic!("#[derive(RlpDecodableWrapper)] is only defined for structs.");
+ };
+
+ let stmt = {
+ let fields: Vec<_> = body.fields.iter().collect();
+ if fields.len() == 1 {
+ let field = fields.first().expect("fields.len() == 1; qed");
+ let mut default_attribute_encountered = false;
+ decodable_field(0, field, decodable_wrapper_parse_quotes(), &mut default_attribute_encountered)
+ } else {
+ panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.")
+ }
+ };
+
+ let name = &ast.ident;
+
+ let impl_block = quote! {
+ impl rlp::Decodable for #name {
+ fn decode(rlp: &rlp::Rlp) -> Result {
+ let result = #name {
+ #stmt
+ };
+
+ Ok(result)
+ }
+ }
+ };
+
+ quote! {
+ const _: () = {
+ extern crate rlp;
+ #impl_block
+ };
+ }
+}
+
+fn decodable_field(
+ mut index: usize,
+ field: &syn::Field,
+ quotes: ParseQuotes,
+ default_attribute_encountered: &mut bool,
+) -> TokenStream {
+ let id = if let Some(ident) = &field.ident {
+ quote! { #ident }
+ } else {
+ let index = syn::Index::from(index);
+ quote! { #index }
+ };
+
+ if *default_attribute_encountered {
+ index -= 1;
+ }
+ let index = quote! { #index };
+
+ let single = quotes.single;
+ let list = quotes.list;
+
+ let attributes = &field.attrs;
+ let default = if let Some(attr) = attributes.iter().find(|attr| attr.path.is_ident("rlp")) {
+ if *default_attribute_encountered {
+ panic!("only 1 #[rlp(default)] attribute is allowed in a struct")
+ }
+ match attr.parse_args() {
+ Ok(proc_macro2::TokenTree::Ident(ident)) if ident == "default" => {}
+ _ => panic!("only #[rlp(default)] attribute is supported"),
+ }
+ *default_attribute_encountered = true;
+ true
+ } else {
+ false
+ };
+
+ if let syn::Type::Path(path) = &field.ty {
+ let ident = &path.path.segments.first().expect("there must be at least 1 segment").ident;
+ let ident_type = ident.to_string();
+ if ident_type == "Vec" {
+ if quotes.takes_index {
+ if default {
+ quote! { #id: #list(#index).unwrap_or_default(), }
+ } else {
+ quote! { #id: #list(#index)?, }
+ }
+ } else {
+ quote! { #id: #list()?, }
+ }
+ } else if quotes.takes_index {
+ if default {
+ quote! { #id: #single(#index).unwrap_or_default(), }
+ } else {
+ quote! { #id: #single(#index)?, }
+ }
+ } else {
+ quote! { #id: #single()?, }
+ }
+ } else {
+ panic!("rlp_derive not supported");
+ }
+}
diff --git a/rlp-derive/src/en.rs b/rlp-derive/src/en.rs
new file mode 100644
index 000000000..9c21bebd2
--- /dev/null
+++ b/rlp-derive/src/en.rs
@@ -0,0 +1,110 @@
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::TokenStream;
+use quote::quote;
+
+pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream {
+ let body = if let syn::Data::Struct(s) = &ast.data {
+ s
+ } else {
+ panic!("#[derive(RlpEncodable)] is only defined for structs.");
+ };
+
+ let stmts: Vec<_> = body.fields.iter().enumerate().map(|(i, field)| encodable_field(i, field)).collect();
+ let name = &ast.ident;
+
+ let stmts_len = stmts.len();
+ let stmts_len = quote! { #stmts_len };
+ let impl_block = quote! {
+ impl rlp::Encodable for #name {
+ fn rlp_append(&self, stream: &mut rlp::RlpStream) {
+ stream.begin_list(#stmts_len);
+ #(#stmts)*
+ }
+ }
+ };
+
+ quote! {
+ const _: () = {
+ extern crate rlp;
+ #impl_block
+ };
+ }
+}
+
+pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream {
+ let body = if let syn::Data::Struct(s) = &ast.data {
+ s
+ } else {
+ panic!("#[derive(RlpEncodableWrapper)] is only defined for structs.");
+ };
+
+ let stmt = {
+ let fields: Vec<_> = body.fields.iter().collect();
+ if fields.len() == 1 {
+ let field = fields.first().expect("fields.len() == 1; qed");
+ encodable_field(0, field)
+ } else {
+ panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.")
+ }
+ };
+
+ let name = &ast.ident;
+
+ let impl_block = quote! {
+ impl rlp::Encodable for #name {
+ fn rlp_append(&self, stream: &mut rlp::RlpStream) {
+ #stmt
+ }
+ }
+ };
+
+ quote! {
+ const _: () = {
+ extern crate rlp;
+ #impl_block
+ };
+ }
+}
+
+fn encodable_field(index: usize, field: &syn::Field) -> TokenStream {
+ let ident = if let Some(ident) = &field.ident {
+ quote! { #ident }
+ } else {
+ let index = syn::Index::from(index);
+ quote! { #index }
+ };
+
+ let id = quote! { self.#ident };
+
+ if let syn::Type::Path(path) = &field.ty {
+ let top_segment = path.path.segments.first().expect("there must be at least 1 segment");
+ let ident = &top_segment.ident;
+ if ident == "Vec" {
+ let inner_ident = {
+ if let syn::PathArguments::AngleBracketed(angle) = &top_segment.arguments {
+ if let syn::GenericArgument::Type(syn::Type::Path(path)) =
+ angle.args.first().expect("Vec has only one angle bracketed type; qed")
+ {
+ &path.path.segments.first().expect("there must be at least 1 segment").ident
+ } else {
+ panic!("rlp_derive not supported");
+ }
+ } else {
+ unreachable!("Vec has only one angle bracketed type; qed")
+ }
+ };
+ quote! { stream.append_list::<#inner_ident, _>(id); }
+ } else {
+ quote! { stream.append(id); }
+ }
+ } else {
+ panic!("rlp_derive not supported");
+ }
+}
diff --git a/rlp-derive/src/lib.rs b/rlp-derive/src/lib.rs
new file mode 100644
index 000000000..cf6edb4f4
--- /dev/null
+++ b/rlp-derive/src/lib.rs
@@ -0,0 +1,56 @@
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Derive macro for `#[derive(RlpEncodable, RlpDecodable)]`.
+//!
+//! For example of usage see `./tests/rlp.rs`.
+//!
+//! This library also supports up to 1 `#[rlp(default)]` in a struct,
+//! which is similar to [`#[serde(default)]`](https://serde.rs/field-attrs.html#default)
+//! with the caveat that we use the `Default` value if
+//! the field deserialization fails, as we don't serialize field
+//! names and there is no way to tell if it is present or not.
+
+#![warn(clippy::all, clippy::pedantic, clippy::nursery)]
+
+extern crate proc_macro;
+
+mod de;
+mod en;
+
+use de::{impl_decodable, impl_decodable_wrapper};
+use en::{impl_encodable, impl_encodable_wrapper};
+use proc_macro::TokenStream;
+
+#[proc_macro_derive(RlpEncodable, attributes(rlp))]
+pub fn encodable(input: TokenStream) -> TokenStream {
+ let ast = syn::parse(input).unwrap();
+ let gen = impl_encodable(&ast);
+ gen.into()
+}
+
+#[proc_macro_derive(RlpEncodableWrapper)]
+pub fn encodable_wrapper(input: TokenStream) -> TokenStream {
+ let ast = syn::parse(input).unwrap();
+ let gen = impl_encodable_wrapper(&ast);
+ gen.into()
+}
+
+#[proc_macro_derive(RlpDecodable, attributes(rlp))]
+pub fn decodable(input: TokenStream) -> TokenStream {
+ let ast = syn::parse(input).unwrap();
+ let gen = impl_decodable(&ast);
+ gen.into()
+}
+
+#[proc_macro_derive(RlpDecodableWrapper)]
+pub fn decodable_wrapper(input: TokenStream) -> TokenStream {
+ let ast = syn::parse(input).unwrap();
+ let gen = impl_decodable_wrapper(&ast);
+ gen.into()
+}
diff --git a/rlp-derive/tests/rlp.rs b/rlp-derive/tests/rlp.rs
new file mode 100644
index 000000000..24963d323
--- /dev/null
+++ b/rlp-derive/tests/rlp.rs
@@ -0,0 +1,71 @@
+// Copyright 2020 Parity Technologies
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use rlp::{decode, encode};
+use rlp_derive::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
+
+#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
+struct Item {
+ a: String,
+}
+
+#[derive(Debug, PartialEq, RlpEncodableWrapper, RlpDecodableWrapper)]
+struct ItemWrapper {
+ a: String,
+}
+
+#[test]
+fn test_encode_item() {
+ let item = Item { a: "cat".into() };
+
+ let expected = vec![0xc4, 0x83, b'c', b'a', b't'];
+ let out = encode(&item);
+ assert_eq!(out, expected);
+
+ let decoded = decode(&expected).expect("decode failure");
+ assert_eq!(item, decoded);
+}
+
+#[test]
+fn test_encode_item_wrapper() {
+ let item = ItemWrapper { a: "cat".into() };
+
+ let expected = vec![0x83, b'c', b'a', b't'];
+ let out = encode(&item);
+ assert_eq!(out, expected);
+
+ let decoded = decode(&expected).expect("decode failure");
+ assert_eq!(item, decoded);
+}
+
+#[test]
+fn test_encode_item_default() {
+ #[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
+ struct ItemDefault {
+ a: String,
+ /// It works with other attributes.
+ #[rlp(default)]
+ b: Option>,
+ }
+
+ let attack_of = "clones";
+ let item = Item { a: attack_of.into() };
+
+ let expected = vec![0xc7, 0x86, b'c', b'l', b'o', b'n', b'e', b's'];
+ let out = encode(&item);
+ assert_eq!(out, expected);
+
+ let item_default = ItemDefault { a: attack_of.into(), b: None };
+
+ let decoded = decode(&expected).expect("default failure");
+ assert_eq!(item_default, decoded);
+
+ let item_some = ItemDefault { a: attack_of.into(), b: Some(vec![1, 2, 3]) };
+ let out = encode(&item_some);
+ assert_eq!(decode(&out), Ok(item_some));
+}
diff --git a/rlp/CHANGELOG.md b/rlp/CHANGELOG.md
index e0a32ca9b..cee20902d 100644
--- a/rlp/CHANGELOG.md
+++ b/rlp/CHANGELOG.md
@@ -1,19 +1,23 @@
# Changelog
-The format is based on [Keep a Changelog].
+The format is based on [Keep a Changelog].
[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
## [Unreleased]
+## [0.4.5] - 2020-03-16
+### Dependencies
+- Updated dependencies. [#361](https://github.com/paritytech/parity-common/pull/361)
+
## [0.4.4] - 2019-11-20
### Added
-- Method `Rlp::at_with_offset` (https://github.com/paritytech/parity-common/pull/269)
+- Method `Rlp::at_with_offset`. [#269](https://github.com/paritytech/parity-common/pull/269)
## [0.4.3] - 2019-10-24
### Dependencies
-- Updated dependencies (https://github.com/paritytech/parity-common/pull/239)
+- Updated dependencies. [#239](https://github.com/paritytech/parity-common/pull/239)
### Fixed
-- Fixed nested unbounded lists (https://github.com/paritytech/parity-common/pull/203)
+- Fixed nested unbounded lists. [#203](https://github.com/paritytech/parity-common/pull/203)
### Added
-- Added no-std support (https://github.com/paritytech/parity-common/pull/206)
+- Added no-std support. [#206](https://github.com/paritytech/parity-common/pull/206)
diff --git a/rlp/Cargo.toml b/rlp/Cargo.toml
index ea0da9b10..cb8694c9e 100644
--- a/rlp/Cargo.toml
+++ b/rlp/Cargo.toml
@@ -1,9 +1,9 @@
[package]
name = "rlp"
-version = "0.4.4"
+version = "0.4.5"
description = "Recursive-length prefix encoding, decoding, and compression"
repository = "https://github.com/paritytech/parity-common"
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
authors = ["Parity Technologies "]
edition = "2018"
@@ -13,7 +13,7 @@ rustc-hex = { version = "2.0.1", default-features = false }
[dev-dependencies]
criterion = "0.3.0"
hex-literal = "0.2.1"
-primitive-types = { path = "../primitive-types", version = "0.6", features = ["impl-rlp"] }
+primitive-types = { path = "../primitive-types", version = "0.7", features = ["impl-rlp"] }
[features]
default = ["std"]
diff --git a/rlp/benches/rlp.rs b/rlp/benches/rlp.rs
index 1fcd8b21f..d1de4c93b 100644
--- a/rlp/benches/rlp.rs
+++ b/rlp/benches/rlp.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2017 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/rlp/src/error.rs b/rlp/src/error.rs
index d810130b0..a965e5626 100644
--- a/rlp/src/error.rs
+++ b/rlp/src/error.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2017 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/rlp/src/impls.rs b/rlp/src/impls.rs
index 4f30b8a59..c4815019f 100644
--- a/rlp/src/impls.rs
+++ b/rlp/src/impls.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2017 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
diff --git a/rlp/src/lib.rs b/rlp/src/lib.rs
index ab386e689..3a913d69f 100644
--- a/rlp/src/lib.rs
+++ b/rlp/src/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2015-2017 Parity Technologies
+// Copyright 2020 Parity Technologies
//
// Licensed under the Apache License, Version 2.0 or the MIT license
@@ -59,14 +59,10 @@ pub const EMPTY_LIST_RLP: [u8; 1] = [0xC0; 1];
/// Shortcut function to decode trusted rlp
///
-/// ```rust
-/// extern crate rlp;
-///
-/// fn main () {
-/// let data = vec![0x83, b'c', b'a', b't'];
-/// let animal: String = rlp::decode(&data).expect("could not decode");
-/// assert_eq!(animal, "cat".to_owned());
-/// }
+/// ```
+/// let data = vec![0x83, b'c', b'a', b't'];
+/// let animal: String = rlp::decode(&data).expect("could not decode");
+/// assert_eq!(animal, "cat".to_owned());
/// ```
pub fn decode