From d42c165ddcf2e8a0d44f92cfc12f81b06d8a373f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 28 Dec 2018 10:33:49 +0100 Subject: [PATCH 01/15] Move a bunch of stuff around (#10101) * Move devtools. * Merge stop_guard & rename memzero * Move price-info to miner. * Group account management * Clean up workspace members. * Move local store closer to miner. * Move clib examples. * Move registrar and hash-fetch * Move rpc_cli/rpc_client * Move stratum closer to miner. * Fix naming convention of crates. * Update Cpp examples path. * Fix paths for clib-example. * Fix removing build. --- Cargo.toml | 16 ++++++ src/de.rs | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/en.rs | 123 ++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 56 +++++++++++++++++++ tests/rlp.rs | 59 ++++++++++++++++++++ 5 files changed, 404 insertions(+) create mode 100644 Cargo.toml create mode 100644 src/de.rs create mode 100644 src/en.rs create mode 100644 src/lib.rs create mode 100644 tests/rlp.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..2087f7524 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rlp_derive" +version = "0.1.0" +authors = ["debris "] + +[lib] +name = "rlp_derive" +proc-macro = true + +[dependencies] +syn = "0.15" +quote = "0.6" +proc-macro2 = "0.4" + +[dev-dependencies] +rlp = { version = "0.3.0", features = ["ethereum"] } diff --git a/src/de.rs b/src/de.rs new file mode 100644 index 000000000..8ab1dd796 --- /dev/null +++ b/src/de.rs @@ -0,0 +1,150 @@ +// 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 . + +use syn; +use proc_macro2::{TokenStream, Span}; + +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 = match ast.data { + syn::Data::Struct(ref s) => s, + _ => panic!("#[derive(RlpDecodable)] is only defined for structs."), + }; + + let stmts: Vec<_> = body.fields.iter().enumerate().map(decodable_field_map).collect(); + let name = &ast.ident; + + let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site()); + let impl_block = quote! { + impl rlp::Decodable for #name { + fn decode(rlp: &rlp::Rlp) -> Result { + let result = #name { + #(#stmts)* + }; + + Ok(result) + } + } + }; + + quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + extern crate rlp; + #impl_block + }; + } +} + +pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { + let body = match ast.data { + syn::Data::Struct(ref s) => s, + _ => 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"); + decodable_field(0, field, decodable_wrapper_parse_quotes()) + } else { + panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.") + } + }; + + let name = &ast.ident; + + let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site()); + let impl_block = quote! { + impl rlp::Decodable for #name { + fn decode(rlp: &rlp::Rlp) -> Result { + let result = #name { + #stmt + }; + + Ok(result) + } + } + }; + + quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + extern crate rlp; + #impl_block + }; + } +} + +fn decodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream { + decodable_field(tuple.0, tuple.1, decodable_parse_quotes()) +} + +fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> TokenStream { + let id = match field.ident { + Some(ref ident) => quote! { #ident }, + None => { + let index: syn::Index = index.into(); + quote! { #index } + } + }; + + let index = quote! { #index }; + + let single = quotes.single; + let list = quotes.list; + + match field.ty { + syn::Type::Path(ref path) => { + let ident = &path.path.segments.first().expect("there must be at least 1 segment").value().ident; + if &ident.to_string() == "Vec" { + if quotes.takes_index { + quote! { #id: #list(#index)?, } + } else { + quote! { #id: #list()?, } + } + } else { + if quotes.takes_index { + quote! { #id: #single(#index)?, } + } else { + quote! { #id: #single()?, } + } + } + }, + _ => panic!("rlp_derive not supported"), + } +} diff --git a/src/en.rs b/src/en.rs new file mode 100644 index 000000000..de7d746e1 --- /dev/null +++ b/src/en.rs @@ -0,0 +1,123 @@ +// 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 . + +use syn; +use proc_macro2::{TokenStream, Span}; + +pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { + let body = match ast.data { + syn::Data::Struct(ref s) => s, + _ => panic!("#[derive(RlpEncodable)] is only defined for structs."), + }; + + let stmts: Vec<_> = body.fields.iter().enumerate().map(encodable_field_map).collect(); + let name = &ast.ident; + + let stmts_len = stmts.len(); + let stmts_len = quote! { #stmts_len }; + let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site()); + let impl_block = quote! { + impl rlp::Encodable for #name { + fn rlp_append(&self, stream: &mut rlp::RlpStream) { + stream.begin_list(#stmts_len); + #(#stmts)* + } + } + }; + + quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + extern crate rlp; + #impl_block + }; + } +} + +pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { + let body = match ast.data { + syn::Data::Struct(ref s) => s, + _ => 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 dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site()); + let impl_block = quote! { + impl rlp::Encodable for #name { + fn rlp_append(&self, stream: &mut rlp::RlpStream) { + #stmt + } + } + }; + + quote! { + #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] + const #dummy_const: () = { + extern crate rlp; + #impl_block + }; + } +} + +fn encodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream { + encodable_field(tuple.0, tuple.1) +} + +fn encodable_field(index: usize, field: &syn::Field) -> TokenStream { + let ident = match field.ident { + Some(ref ident) => quote! { #ident }, + None => { + let index: syn::Index = index.into(); + quote! { #index } + } + }; + + let id = quote! { self.#ident }; + + match field.ty { + syn::Type::Path(ref path) => { + let top_segment = path.path.segments.first().expect("there must be at least 1 segment"); + let ident = &top_segment.value().ident; + if &ident.to_string() == "Vec" { + let inner_ident = match top_segment.value().arguments { + syn::PathArguments::AngleBracketed(ref angle) => { + let ty = angle.args.first().expect("Vec has only one angle bracketed type; qed"); + match **ty.value() { + syn::GenericArgument::Type(syn::Type::Path(ref path)) => &path.path.segments.first().expect("there must be at least 1 segment").value().ident, + _ => panic!("rlp_derive not supported"), + } + }, + _ => unreachable!("Vec has only one angle bracketed type; qed"), + }; + quote! { stream.append_list::<#inner_ident, _>(&#id); } + } else { + quote! { stream.append(&#id); } + } + }, + _ => panic!("rlp_derive not supported"), + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 000000000..5b0cc2a62 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,56 @@ +// 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 . + +extern crate proc_macro; +extern crate proc_macro2; +extern crate syn; +#[macro_use] +extern crate quote; + +mod en; +mod de; + +use proc_macro::TokenStream; +use en::{impl_encodable, impl_encodable_wrapper}; +use de::{impl_decodable, impl_decodable_wrapper}; + +#[proc_macro_derive(RlpEncodable)] +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)] +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/tests/rlp.rs b/tests/rlp.rs new file mode 100644 index 000000000..41cfed17c --- /dev/null +++ b/tests/rlp.rs @@ -0,0 +1,59 @@ +// 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 . + +extern crate rlp; +#[macro_use] +extern crate rlp_derive; + +use rlp::{encode, decode}; + +#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] +struct Foo { + a: String, +} + +#[derive(Debug, PartialEq, RlpEncodableWrapper, RlpDecodableWrapper)] +struct FooWrapper { + a: String, +} + +#[test] +fn test_encode_foo() { + let foo = Foo { + a: "cat".into(), + }; + + let expected = vec![0xc4, 0x83, b'c', b'a', b't']; + let out = encode(&foo); + assert_eq!(out, expected); + + let decoded = decode(&expected).expect("decode failure"); + assert_eq!(foo, decoded); +} + +#[test] +fn test_encode_foo_wrapper() { + let foo = FooWrapper { + a: "cat".into(), + }; + + let expected = vec![0x83, b'c', b'a', b't']; + let out = encode(&foo); + assert_eq!(out, expected); + + let decoded = decode(&expected).expect("decode failure"); + assert_eq!(foo, decoded); +} From ac0d1169e3dbca3a002cec4d1b756917750ccb74 Mon Sep 17 00:00:00 2001 From: Afri Schoedon <5chdn@users.noreply.github.com> Date: Mon, 7 Jan 2019 11:33:07 +0100 Subject: [PATCH 02/15] misc: bump license header to 2019 (#10135) * misc: bump license header to 2019 * misc: remove_duplicate_empty_lines.sh * misc: run license header script * commit cargo lock --- src/de.rs | 10 +++++----- src/en.rs | 10 +++++----- src/lib.rs | 10 +++++----- tests/rlp.rs | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/de.rs b/src/de.rs index 8ab1dd796..234bcbcb8 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,18 +1,18 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. -// Parity is free software: you can redistribute it and/or modify +// Parity Ethereum 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, +// Parity Ethereum 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 . +// along with Parity Ethereum. If not, see . use syn; use proc_macro2::{TokenStream, Span}; diff --git a/src/en.rs b/src/en.rs index de7d746e1..95e5b9142 100644 --- a/src/en.rs +++ b/src/en.rs @@ -1,18 +1,18 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. -// Parity is free software: you can redistribute it and/or modify +// Parity Ethereum 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, +// Parity Ethereum 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 . +// along with Parity Ethereum. If not, see . use syn; use proc_macro2::{TokenStream, Span}; diff --git a/src/lib.rs b/src/lib.rs index 5b0cc2a62..0f5d442f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,18 +1,18 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. -// Parity is free software: you can redistribute it and/or modify +// Parity Ethereum 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, +// Parity Ethereum 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 . +// along with Parity Ethereum. If not, see . extern crate proc_macro; extern crate proc_macro2; diff --git a/tests/rlp.rs b/tests/rlp.rs index 41cfed17c..a6819ba4b 100644 --- a/tests/rlp.rs +++ b/tests/rlp.rs @@ -1,18 +1,18 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. +// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// This file is part of Parity Ethereum. -// Parity is free software: you can redistribute it and/or modify +// Parity Ethereum 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, +// Parity Ethereum 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 . +// along with Parity Ethereum. If not, see . extern crate rlp; #[macro_use] From 4cec571b94a9005ca09de448428d38ff1b53d015 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Mon, 3 Jun 2019 15:36:21 +0200 Subject: [PATCH 03/15] Upgrade ethereum types (#10670) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * cargo upgrade "ethereum-types" --all --allow-prerelease * [ethash] fix compilation errors * [ethkey] fix compilation errors * [journaldb] fix compilation errors * [dir] fix compilation errors * [ethabi] update to 0.7 * wip * [eip-712] fix compilation errors * [ethjson] fix compilation errors * [Cargo.toml] add TODO to remove patches * [ethstore] fix compilation errors * use patched keccak-hash with new primitive-types * wip * [ethcore-network-devp2p] fix compilation errors * [vm] fix compilation errors * [common-types, evm, wasm] fix compilation errors * [ethcore-db] Require AsRef instead of Deref for keys * [ethcore-blockchain] fix some compilation errors * [blooms-db] fix compilation errors Thanks a lot @dvdplm :) * we don't need no rlp ethereum feature * [ethcore] fix some compilation errors * [parity-ipfs-api] fix compilation error * [ethcore-light] fix compilation errors * [Cargo.lock] update parity-common * [ethcore-private-tx] fix some compilation errors * wip * [ethcore-private-tx] fix compilation errors * [parity-updater] fix compilation errors * [parity-rpc] fix compilation errors * [parity-bin] fix other compilation errors * update to new ethereum-types * update keccak-hash * [fastmap] fix compilation in tests * [blooms-db] fix compilation in tests * [common-types] fix compilation in tests * [triehash-ethereum] fix compilation in tests * [ethkey] fix compilation in tests * [pwasm-run-test] fix compilation errors * [wasm] fix compilation errors * [ethjson] fix compilation in tests * [eip-712] fix compilation in tests * [ethcore-blockchain] fix compilation in tests * [ethstore] fix compilation in tests * [ethstore-accounts] fix compilation in tests * [parity-hash-fetch] fix compilation in tests * [parity-whisper] fix compilation in tests * [ethcore-miner] fix compilation in tests * [ethcore-network-devp2p] fix compilation in tests * [*] upgrade rand to 0.6 * [evm] get rid of num-bigint conversions * [ethcore] downgrade trie-standardmap and criterion * [ethcore] fix some warnings * [ethcore] fix compilation in tests * [evmbin] fix compilation in tests * [updater] fix compilation in tests * [ethash] fix compilation in tests * [ethcore-secretstore] fix compilation in tests * [ethcore-sync] fix compilation in tests * [parity-rpc] fix compilation in tests * [ethcore] finally fix compilation in tests FUCK YEAH!!! * [ethstore] lazy_static is unused * [ethcore] fix test * fix up bad merge * [Cargo.toml] remove unused patches * [*] replace some git dependencies with crates.io * [Cargo.toml] remove unused lazy_static * [*] clean up * [ethcore] fix transaction_filter_deprecated test * [private-tx] fix serialization tests * fix more serialization tests * [ethkey] fix smoky test * [rpc] fix tests, please? * [ethcore] remove commented out code * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga * [ethstore] remove unused dev-dependency * [ethcore] remove resolved TODO * [*] resolve keccak-hash TODO * [*] s/Address::default()/Address::zero() * [rpc] remove Subscribers::new_test * [rpc] remove EthPubSubClient::new_test * [ethcore] use trie-standardmap from crates.io * [dir] fix db_root_path * [ethcore] simplify snapshot::tests::helpers::fill_storage * Apply suggestions from code review Co-Authored-By: David * [ethcore-secretstore] resolve TODO in serialization * [ethcore-network-devp2p] resolve TODO in save_key * [Cargo.lock] update triehash * [*] use ethabi from crates.io * [ethkey] use secp256k1 from master branch * [Cargo.lock] update eth-secp256k1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2087f7524..ba5fb984f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,4 @@ quote = "0.6" proc-macro2 = "0.4" [dev-dependencies] -rlp = { version = "0.3.0", features = ["ethereum"] } +rlp = "0.4.0" From a09c42b779b0ba044cfc03e3617f5faaf18acbdc Mon Sep 17 00:00:00 2001 From: s3krit Date: Fri, 17 Jan 2020 14:27:28 +0100 Subject: [PATCH 04/15] Update copyright notice 2020 (#11386) * Update copyright noticed 2020 * Update copyright in two overlooked files --- src/de.rs | 2 +- src/en.rs | 2 +- src/lib.rs | 2 +- tests/rlp.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/de.rs b/src/de.rs index 234bcbcb8..b59d310e3 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Parity Ethereum. // Parity Ethereum is free software: you can redistribute it and/or modify diff --git a/src/en.rs b/src/en.rs index 95e5b9142..828ad6b0f 100644 --- a/src/en.rs +++ b/src/en.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Parity Ethereum. // Parity Ethereum is free software: you can redistribute it and/or modify diff --git a/src/lib.rs b/src/lib.rs index 0f5d442f4..15757ffd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Parity Ethereum. // Parity Ethereum is free software: you can redistribute it and/or modify diff --git a/tests/rlp.rs b/tests/rlp.rs index a6819ba4b..0e78c169e 100644 --- a/tests/rlp.rs +++ b/tests/rlp.rs @@ -1,4 +1,4 @@ -// Copyright 2015-2019 Parity Technologies (UK) Ltd. +// Copyright 2015-2020 Parity Technologies (UK) Ltd. // This file is part of Parity Ethereum. // Parity Ethereum is free software: you can redistribute it and/or modify From 96d0d4899cd66213aef4e16029a8ad00a151628f Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Tue, 4 Feb 2020 17:35:48 +0100 Subject: [PATCH 05/15] rlp_derive: cleanup (#11446) * rlp_derive: update syn & co * rlp_derive: remove dummy_const * rlp_derive: remove unused attirubutes * rlp-derive: change authors --- Cargo.toml | 9 +++++---- src/de.rs | 28 +++++++++++++++++----------- src/en.rs | 49 ++++++++++++++++++++++++++++++++----------------- src/lib.rs | 10 +++------- tests/rlp.rs | 15 ++++----------- 5 files changed, 61 insertions(+), 50 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ba5fb984f..878b80167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,16 +1,17 @@ [package] name = "rlp_derive" version = "0.1.0" -authors = ["debris "] +authors = ["Parity Technologies "] +edition = "2018" [lib] name = "rlp_derive" proc-macro = true [dependencies] -syn = "0.15" -quote = "0.6" -proc-macro2 = "0.4" +syn = "1.0.14" +quote = "1.0.2" +proc-macro2 = "1.0.8" [dev-dependencies] rlp = "0.4.0" diff --git a/src/de.rs b/src/de.rs index b59d310e3..b35ece3f9 100644 --- a/src/de.rs +++ b/src/de.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use syn; -use proc_macro2::{TokenStream, Span}; +use proc_macro2::TokenStream; +use quote::quote; struct ParseQuotes { single: TokenStream, @@ -45,10 +45,14 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream { _ => panic!("#[derive(RlpDecodable)] is only defined for structs."), }; - let stmts: Vec<_> = body.fields.iter().enumerate().map(decodable_field_map).collect(); + let stmts: Vec<_> = body + .fields + .iter() + .enumerate() + .map(decodable_field_map) + .collect(); let name = &ast.ident; - let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site()); let impl_block = quote! { impl rlp::Decodable for #name { fn decode(rlp: &rlp::Rlp) -> Result { @@ -62,8 +66,7 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream { }; quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { + const _: () = { extern crate rlp; #impl_block }; @@ -88,7 +91,6 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; - let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_DECODABLE_FOR_{}", name), Span::call_site()); let impl_block = quote! { impl rlp::Decodable for #name { fn decode(rlp: &rlp::Rlp) -> Result { @@ -102,8 +104,7 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { }; quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { + const _: () = { extern crate rlp; #impl_block }; @@ -130,7 +131,12 @@ fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> Tok match field.ty { syn::Type::Path(ref path) => { - let ident = &path.path.segments.first().expect("there must be at least 1 segment").value().ident; + let ident = &path + .path + .segments + .first() + .expect("there must be at least 1 segment") + .ident; if &ident.to_string() == "Vec" { if quotes.takes_index { quote! { #id: #list(#index)?, } @@ -144,7 +150,7 @@ fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> Tok quote! { #id: #single()?, } } } - }, + } _ => panic!("rlp_derive not supported"), } } diff --git a/src/en.rs b/src/en.rs index 828ad6b0f..6bb22f8dc 100644 --- a/src/en.rs +++ b/src/en.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -use syn; -use proc_macro2::{TokenStream, Span}; +use proc_macro2::TokenStream; +use quote::quote; pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { let body = match ast.data { @@ -23,12 +23,16 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { _ => panic!("#[derive(RlpEncodable)] is only defined for structs."), }; - let stmts: Vec<_> = body.fields.iter().enumerate().map(encodable_field_map).collect(); + let stmts: Vec<_> = body + .fields + .iter() + .enumerate() + .map(encodable_field_map) + .collect(); let name = &ast.ident; let stmts_len = stmts.len(); let stmts_len = quote! { #stmts_len }; - let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site()); let impl_block = quote! { impl rlp::Encodable for #name { fn rlp_append(&self, stream: &mut rlp::RlpStream) { @@ -39,8 +43,7 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { }; quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { + const _: () = { extern crate rlp; #impl_block }; @@ -65,7 +68,6 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; - let dummy_const = syn::Ident::new(&format!("_IMPL_RLP_ENCODABLE_FOR_{}", name), Span::call_site()); let impl_block = quote! { impl rlp::Encodable for #name { fn rlp_append(&self, stream: &mut rlp::RlpStream) { @@ -75,8 +77,7 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { }; quote! { - #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] - const #dummy_const: () = { + const _: () = { extern crate rlp; #impl_block }; @@ -100,24 +101,38 @@ fn encodable_field(index: usize, field: &syn::Field) -> TokenStream { match field.ty { syn::Type::Path(ref path) => { - let top_segment = path.path.segments.first().expect("there must be at least 1 segment"); - let ident = &top_segment.value().ident; + let top_segment = path + .path + .segments + .first() + .expect("there must be at least 1 segment"); + let ident = &top_segment.ident; if &ident.to_string() == "Vec" { - let inner_ident = match top_segment.value().arguments { + let inner_ident = match top_segment.arguments { syn::PathArguments::AngleBracketed(ref angle) => { - let ty = angle.args.first().expect("Vec has only one angle bracketed type; qed"); - match **ty.value() { - syn::GenericArgument::Type(syn::Type::Path(ref path)) => &path.path.segments.first().expect("there must be at least 1 segment").value().ident, + let ty = angle + .args + .first() + .expect("Vec has only one angle bracketed type; qed"); + match *ty { + syn::GenericArgument::Type(syn::Type::Path(ref path)) => { + &path + .path + .segments + .first() + .expect("there must be at least 1 segment") + .ident + } _ => panic!("rlp_derive not supported"), } - }, + } _ => unreachable!("Vec has only one angle bracketed type; qed"), }; quote! { stream.append_list::<#inner_ident, _>(&#id); } } else { quote! { stream.append(&#id); } } - }, + } _ => panic!("rlp_derive not supported"), } } diff --git a/src/lib.rs b/src/lib.rs index 15757ffd6..09d29d250 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,17 +15,13 @@ // along with Parity Ethereum. If not, see . extern crate proc_macro; -extern crate proc_macro2; -extern crate syn; -#[macro_use] -extern crate quote; -mod en; mod de; +mod en; -use proc_macro::TokenStream; -use en::{impl_encodable, impl_encodable_wrapper}; use de::{impl_decodable, impl_decodable_wrapper}; +use en::{impl_encodable, impl_encodable_wrapper}; +use proc_macro::TokenStream; #[proc_macro_derive(RlpEncodable)] pub fn encodable(input: TokenStream) -> TokenStream { diff --git a/tests/rlp.rs b/tests/rlp.rs index 0e78c169e..f3889ed18 100644 --- a/tests/rlp.rs +++ b/tests/rlp.rs @@ -14,11 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity Ethereum. If not, see . -extern crate rlp; -#[macro_use] -extern crate rlp_derive; - -use rlp::{encode, decode}; +use rlp::{decode, encode}; +use rlp_derive::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; #[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] struct Foo { @@ -32,9 +29,7 @@ struct FooWrapper { #[test] fn test_encode_foo() { - let foo = Foo { - a: "cat".into(), - }; + let foo = Foo { a: "cat".into() }; let expected = vec![0xc4, 0x83, b'c', b'a', b't']; let out = encode(&foo); @@ -46,9 +41,7 @@ fn test_encode_foo() { #[test] fn test_encode_foo_wrapper() { - let foo = FooWrapper { - a: "cat".into(), - }; + let foo = FooWrapper { a: "cat".into() }; let expected = vec![0x83, b'c', b'a', b't']; let out = encode(&foo); From 66af133da31e979a5e487c86769932c6c0659af5 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 5 Feb 2020 15:30:45 +0100 Subject: [PATCH 06/15] backwards compatible call_type creation_method (#11450) * rlp_derive: update syn & co * rlp_derive: remove dummy_const * rlp_derive: remove unused attirubutes * rlp-derive: change authors * rlp_derive: add rlp(default) attribute * Revert "Revert "[Trace] Distinguish between `create` and `create2` (#11311)" (#11427)" This reverts commit 5d4993b0f856bf9e0e2c78849b72e581f0cde686. * trace: backwards compatible call_type and creation_method * trace: add rlp backward compatibility tests * cleanup * i know, i hate backwards compatibility too * address review grumbles --- src/de.rs | 59 ++++++++++++++++++++++++++++++++++++++++++---------- src/en.rs | 6 +----- src/lib.rs | 4 ++-- tests/rlp.rs | 27 ++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 18 deletions(-) diff --git a/src/de.rs b/src/de.rs index b35ece3f9..3ae4b3aff 100644 --- a/src/de.rs +++ b/src/de.rs @@ -45,12 +45,17 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream { _ => panic!("#[derive(RlpDecodable)] is only defined for structs."), }; + let mut default_attribute_encountered = false; let stmts: Vec<_> = body .fields .iter() .enumerate() - .map(decodable_field_map) - .collect(); + .map(|(i, field)| decodable_field( + i, + field, + decodable_parse_quotes(), + &mut default_attribute_encountered, + )).collect(); let name = &ast.ident; let impl_block = quote! { @@ -83,7 +88,13 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { let fields: Vec<_> = body.fields.iter().collect(); if fields.len() == 1 { let field = fields.first().expect("fields.len() == 1; qed"); - decodable_field(0, field, decodable_wrapper_parse_quotes()) + 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.") } @@ -111,11 +122,12 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { } } -fn decodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream { - decodable_field(tuple.0, tuple.1, decodable_parse_quotes()) -} - -fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> TokenStream { +fn decodable_field( + index: usize, + field: &syn::Field, + quotes: ParseQuotes, + default_attribute_encountered: &mut bool, +) -> TokenStream { let id = match field.ident { Some(ref ident) => quote! { #ident }, None => { @@ -124,11 +136,27 @@ fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> Tok } }; + let index = index - *default_attribute_encountered as usize; 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.to_string() == "default" => {}, + _ => panic!("only #[rlp(default)] attribute is supported"), + } + *default_attribute_encountered = true; + true + } else { + false + }; + match field.ty { syn::Type::Path(ref path) => { let ident = &path @@ -137,15 +165,24 @@ fn decodable_field(index: usize, field: &syn::Field, quotes: ParseQuotes) -> Tok .first() .expect("there must be at least 1 segment") .ident; - if &ident.to_string() == "Vec" { + let ident_type = ident.to_string(); + if &ident_type == "Vec" { if quotes.takes_index { - quote! { #id: #list(#index)?, } + if default { + quote! { #id: #list(#index).unwrap_or_default(), } + } else { + quote! { #id: #list(#index)?, } + } } else { quote! { #id: #list()?, } } } else { if quotes.takes_index { - quote! { #id: #single(#index)?, } + if default { + quote! { #id: #single(#index).unwrap_or_default(), } + } else { + quote! { #id: #single(#index)?, } + } } else { quote! { #id: #single()?, } } diff --git a/src/en.rs b/src/en.rs index 6bb22f8dc..32905456a 100644 --- a/src/en.rs +++ b/src/en.rs @@ -27,7 +27,7 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { .fields .iter() .enumerate() - .map(encodable_field_map) + .map(|(i, field)| encodable_field(i, field)) .collect(); let name = &ast.ident; @@ -84,10 +84,6 @@ pub fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { } } -fn encodable_field_map(tuple: (usize, &syn::Field)) -> TokenStream { - encodable_field(tuple.0, tuple.1) -} - fn encodable_field(index: usize, field: &syn::Field) -> TokenStream { let ident = match field.ident { Some(ref ident) => quote! { #ident }, diff --git a/src/lib.rs b/src/lib.rs index 09d29d250..3c9799e2a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ use de::{impl_decodable, impl_decodable_wrapper}; use en::{impl_encodable, impl_encodable_wrapper}; use proc_macro::TokenStream; -#[proc_macro_derive(RlpEncodable)] +#[proc_macro_derive(RlpEncodable, attributes(rlp))] pub fn encodable(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); let gen = impl_encodable(&ast); @@ -37,7 +37,7 @@ pub fn encodable_wrapper(input: TokenStream) -> TokenStream { gen.into() } -#[proc_macro_derive(RlpDecodable)] +#[proc_macro_derive(RlpDecodable, attributes(rlp))] pub fn decodable(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); let gen = impl_decodable(&ast); diff --git a/tests/rlp.rs b/tests/rlp.rs index f3889ed18..adf737667 100644 --- a/tests/rlp.rs +++ b/tests/rlp.rs @@ -50,3 +50,30 @@ fn test_encode_foo_wrapper() { let decoded = decode(&expected).expect("decode failure"); assert_eq!(foo, decoded); } + +#[test] +fn test_encode_foo_default() { + #[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] + struct FooDefault { + a: String, + /// It works with other attributes. + #[rlp(default)] + b: Option>, + } + + let attack_of = String::from("clones"); + let foo = Foo { a: attack_of.clone() }; + + let expected = vec![0xc7, 0x86, b'c', b'l', b'o', b'n', b'e', b's']; + let out = encode(&foo); + assert_eq!(out, expected); + + let foo_default = FooDefault { a: attack_of.clone(), b: None }; + + let decoded = decode(&expected).expect("default failure"); + assert_eq!(foo_default, decoded); + + let foo_some = FooDefault { a: attack_of.clone(), b: Some(vec![1, 2, 3]) }; + let out = encode(&foo_some); + assert_eq!(decode(&out), Ok(foo_some)); +} From d212afdc1d3b75d3bf85b2bd339e6cd6ce617833 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 15:39:55 +0100 Subject: [PATCH 07/15] rlp-derive: change license and add a changelog --- rlp-derive/CHANGELOG.md | 10 ++++++++++ rlp-derive/Cargo.toml | 3 +++ rlp-derive/src/de.rs | 20 ++++++-------------- rlp-derive/src/en.rs | 20 ++++++-------------- rlp-derive/src/lib.rs | 22 ++++++++-------------- 5 files changed, 33 insertions(+), 42 deletions(-) create mode 100644 rlp-derive/CHANGELOG.md diff --git a/rlp-derive/CHANGELOG.md b/rlp-derive/CHANGELOG.md new file mode 100644 index 000000000..592d3fbf9 --- /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-12 +- 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 index 878b80167..f2b8133c1 100644 --- a/rlp-derive/Cargo.toml +++ b/rlp-derive/Cargo.toml @@ -2,6 +2,9 @@ name = "rlp_derive" version = "0.1.0" authors = ["Parity Technologies "] +license = "MIT/Apache-2.0" +description = "Derive macro for #[derive(RlpEncodable, RlpDecodable)]" +homepage = "http://parity.io" edition = "2018" [lib] diff --git a/rlp-derive/src/de.rs b/rlp-derive/src/de.rs index 3ae4b3aff..c71f30810 100644 --- a/rlp-derive/src/de.rs +++ b/rlp-derive/src/de.rs @@ -1,18 +1,10 @@ // Copyright 2015-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . +// +// 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; diff --git a/rlp-derive/src/en.rs b/rlp-derive/src/en.rs index 32905456a..44e0f60da 100644 --- a/rlp-derive/src/en.rs +++ b/rlp-derive/src/en.rs @@ -1,18 +1,10 @@ // Copyright 2015-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . +// +// 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; diff --git a/rlp-derive/src/lib.rs b/rlp-derive/src/lib.rs index 3c9799e2a..c8170d07b 100644 --- a/rlp-derive/src/lib.rs +++ b/rlp-derive/src/lib.rs @@ -1,18 +1,12 @@ // Copyright 2015-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . +// +// 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)]`. extern crate proc_macro; From 602d1b90f2403ad1c58ff52144dd81db1c33ddfd Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 15:41:25 +0100 Subject: [PATCH 08/15] rlp-derive: tests license header as well --- rlp-derive/tests/rlp.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/rlp-derive/tests/rlp.rs b/rlp-derive/tests/rlp.rs index adf737667..e3cda4dbc 100644 --- a/rlp-derive/tests/rlp.rs +++ b/rlp-derive/tests/rlp.rs @@ -1,18 +1,10 @@ // Copyright 2015-2020 Parity Technologies (UK) Ltd. -// This file is part of Parity Ethereum. - -// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see . +// +// 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}; From d1ffe961053b6fd361f99d096dc7eda0bf716128 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 15:42:05 +0100 Subject: [PATCH 09/15] add rlp-derive to workspace --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 15633c072..019b989de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ "parity-path", "plain_hasher", "rlp", + "rlp-derive", "runtime", "transaction-pool", "trace-time", From 17aceb8c40b815f39d75037510a99049aa6dc25f Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 15:49:31 +0100 Subject: [PATCH 10/15] rename to rlp-derive --- rlp-derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rlp-derive/Cargo.toml b/rlp-derive/Cargo.toml index f2b8133c1..850dfd5e4 100644 --- a/rlp-derive/Cargo.toml +++ b/rlp-derive/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rlp_derive" +name = "rlp-derive" version = "0.1.0" authors = ["Parity Technologies "] license = "MIT/Apache-2.0" From 0583646bc8031c663f05eb2034440521e03a20df Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 15:50:04 +0100 Subject: [PATCH 11/15] remove unnecessary line --- rlp-derive/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/rlp-derive/Cargo.toml b/rlp-derive/Cargo.toml index 850dfd5e4..bf4d0eaf0 100644 --- a/rlp-derive/Cargo.toml +++ b/rlp-derive/Cargo.toml @@ -8,7 +8,6 @@ homepage = "http://parity.io" edition = "2018" [lib] -name = "rlp_derive" proc-macro = true [dependencies] From 2a7c2f82a5511fd4ea795e408fa61b8c5fe90eb4 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 15:58:53 +0100 Subject: [PATCH 12/15] rlp-derive: more module docs --- rlp-derive/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rlp-derive/src/lib.rs b/rlp-derive/src/lib.rs index c8170d07b..47efd2ffe 100644 --- a/rlp-derive/src/lib.rs +++ b/rlp-derive/src/lib.rs @@ -7,6 +7,14 @@ // 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. extern crate proc_macro; From 194a1bdf25e6323816af24ef340dbe07dd09a7f7 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 16:15:08 +0100 Subject: [PATCH 13/15] cargo fmt --- rlp-derive/src/de.rs | 36 +++++++----------------------------- rlp-derive/src/en.rs | 25 ++++--------------------- 2 files changed, 11 insertions(+), 50 deletions(-) diff --git a/rlp-derive/src/de.rs b/rlp-derive/src/de.rs index c71f30810..d1b4e4ca5 100644 --- a/rlp-derive/src/de.rs +++ b/rlp-derive/src/de.rs @@ -16,19 +16,11 @@ struct ParseQuotes { } fn decodable_parse_quotes() -> ParseQuotes { - ParseQuotes { - single: quote! { rlp.val_at }, - list: quote! { rlp.list_at }, - takes_index: true, - } + 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, - } + ParseQuotes { single: quote! { rlp.as_val }, list: quote! { rlp.as_list }, takes_index: false } } pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream { @@ -42,12 +34,8 @@ pub fn impl_decodable(ast: &syn::DeriveInput) -> TokenStream { .fields .iter() .enumerate() - .map(|(i, field)| decodable_field( - i, - field, - decodable_parse_quotes(), - &mut default_attribute_encountered, - )).collect(); + .map(|(i, field)| decodable_field(i, field, decodable_parse_quotes(), &mut default_attribute_encountered)) + .collect(); let name = &ast.ident; let impl_block = quote! { @@ -81,12 +69,7 @@ pub fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> TokenStream { 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, - ) + decodable_field(0, field, decodable_wrapper_parse_quotes(), &mut default_attribute_encountered) } else { panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.") } @@ -140,7 +123,7 @@ fn decodable_field( panic!("only 1 #[rlp(default)] attribute is allowed in a struct") } match attr.parse_args() { - Ok(proc_macro2::TokenTree::Ident(ident)) if ident.to_string() == "default" => {}, + Ok(proc_macro2::TokenTree::Ident(ident)) if ident.to_string() == "default" => {} _ => panic!("only #[rlp(default)] attribute is supported"), } *default_attribute_encountered = true; @@ -151,12 +134,7 @@ fn decodable_field( match field.ty { syn::Type::Path(ref path) => { - let ident = &path - .path - .segments - .first() - .expect("there must be at least 1 segment") - .ident; + 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 { diff --git a/rlp-derive/src/en.rs b/rlp-derive/src/en.rs index 44e0f60da..9eb0d6afb 100644 --- a/rlp-derive/src/en.rs +++ b/rlp-derive/src/en.rs @@ -15,12 +15,7 @@ pub fn impl_encodable(ast: &syn::DeriveInput) -> TokenStream { _ => panic!("#[derive(RlpEncodable)] is only defined for structs."), }; - let stmts: Vec<_> = body - .fields - .iter() - .enumerate() - .map(|(i, field)| encodable_field(i, field)) - .collect(); + let stmts: Vec<_> = body.fields.iter().enumerate().map(|(i, field)| encodable_field(i, field)).collect(); let name = &ast.ident; let stmts_len = stmts.len(); @@ -89,27 +84,15 @@ fn encodable_field(index: usize, field: &syn::Field) -> TokenStream { match field.ty { syn::Type::Path(ref path) => { - let top_segment = path - .path - .segments - .first() - .expect("there must be at least 1 segment"); + let top_segment = path.path.segments.first().expect("there must be at least 1 segment"); let ident = &top_segment.ident; if &ident.to_string() == "Vec" { let inner_ident = match top_segment.arguments { syn::PathArguments::AngleBracketed(ref angle) => { - let ty = angle - .args - .first() - .expect("Vec has only one angle bracketed type; qed"); + let ty = angle.args.first().expect("Vec has only one angle bracketed type; qed"); match *ty { syn::GenericArgument::Type(syn::Type::Path(ref path)) => { - &path - .path - .segments - .first() - .expect("there must be at least 1 segment") - .ident + &path.path.segments.first().expect("there must be at least 1 segment").ident } _ => panic!("rlp_derive not supported"), } From 5f21a4f30f38996eaadec68d0accc67f9122a6ad Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 16:38:05 +0100 Subject: [PATCH 14/15] trigger the ci --- rlp-derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rlp-derive/Cargo.toml b/rlp-derive/Cargo.toml index bf4d0eaf0..54541128a 100644 --- a/rlp-derive/Cargo.toml +++ b/rlp-derive/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" proc-macro = true [dependencies] -syn = "1.0.14" +syn = "1.0" quote = "1.0.2" proc-macro2 = "1.0.8" From 0a503a67891535f07f9e5ff19fff247fcb1b66b9 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Wed, 12 Feb 2020 16:38:24 +0100 Subject: [PATCH 15/15] Revert "trigger the ci" This reverts commit 5f21a4f30f38996eaadec68d0accc67f9122a6ad. --- rlp-derive/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rlp-derive/Cargo.toml b/rlp-derive/Cargo.toml index 54541128a..bf4d0eaf0 100644 --- a/rlp-derive/Cargo.toml +++ b/rlp-derive/Cargo.toml @@ -11,7 +11,7 @@ edition = "2018" proc-macro = true [dependencies] -syn = "1.0" +syn = "1.0.14" quote = "1.0.2" proc-macro2 = "1.0.8"