update to published rlp-derive (#11489)
This commit is contained in:
		
							parent
							
								
									9477bae6dc
								
							
						
					
					
						commit
						3424697313
					
				
							
								
								
									
										37
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										37
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -710,7 +710,7 @@ dependencies = [
 | 
			
		||||
 "parity-util-mem",
 | 
			
		||||
 "patricia-trie-ethereum",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
 "rustc-hex 2.1.0",
 | 
			
		||||
 "unexpected",
 | 
			
		||||
 "vm",
 | 
			
		||||
@ -1010,7 +1010,7 @@ dependencies = [
 | 
			
		||||
 "hex-literal",
 | 
			
		||||
 "maplit",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -1307,8 +1307,8 @@ dependencies = [
 | 
			
		||||
 "rand 0.7.2",
 | 
			
		||||
 "rayon",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
 "rlp_compress",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rustc-hex 1.0.0",
 | 
			
		||||
 "tempdir",
 | 
			
		||||
 "triehash-ethereum",
 | 
			
		||||
@ -1359,7 +1359,7 @@ dependencies = [
 | 
			
		||||
 "parity-util-mem",
 | 
			
		||||
 "parking_lot 0.10.0",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
@ -1415,7 +1415,7 @@ dependencies = [
 | 
			
		||||
 "patricia-trie-ethereum",
 | 
			
		||||
 "rand 0.7.2",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
 "serde",
 | 
			
		||||
 "serde_derive",
 | 
			
		||||
 "smallvec 1.2.0",
 | 
			
		||||
@ -1566,7 +1566,7 @@ dependencies = [
 | 
			
		||||
 "patricia-trie-ethereum",
 | 
			
		||||
 "registrar",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
 "rustc-hex 1.0.0",
 | 
			
		||||
 "serde",
 | 
			
		||||
 "serde_derive",
 | 
			
		||||
@ -4317,6 +4317,17 @@ dependencies = [
 | 
			
		||||
 "rustc-hex 2.1.0",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rlp-derive"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2 1.0.8",
 | 
			
		||||
 "quote 1.0.2",
 | 
			
		||||
 "syn 1.0.14",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rlp_compress"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
@ -4326,16 +4337,6 @@ dependencies = [
 | 
			
		||||
 "rlp",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rlp_derive"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "proc-macro2 1.0.8",
 | 
			
		||||
 "quote 1.0.2",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "syn 1.0.14",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "rocksdb"
 | 
			
		||||
version = "0.13.0"
 | 
			
		||||
@ -4709,7 +4710,7 @@ dependencies = [
 | 
			
		||||
 "rand 0.7.2",
 | 
			
		||||
 "rand_xorshift 0.2.0",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
 "scopeguard 1.0.0",
 | 
			
		||||
 "snapshot-tests",
 | 
			
		||||
 "spec",
 | 
			
		||||
@ -5358,7 +5359,7 @@ dependencies = [
 | 
			
		||||
 "parity-util-mem",
 | 
			
		||||
 "parking_lot 0.10.0",
 | 
			
		||||
 "rlp",
 | 
			
		||||
 "rlp_derive",
 | 
			
		||||
 "rlp-derive",
 | 
			
		||||
 "vm",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,7 @@ parking_lot = "0.10.0"
 | 
			
		||||
rayon = "1.0"
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_compress = { path = "../../util/rlp-compress" }
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
triehash-ethereum = { version = "0.2",  path = "../../util/triehash-ethereum" }
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
 | 
			
		||||
@ -14,4 +14,4 @@ kvdb = "0.4.0"
 | 
			
		||||
parity-util-mem = "0.5.1"
 | 
			
		||||
parking_lot = "0.10.0"
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ vm = { path = "../vm" }
 | 
			
		||||
fastmap = { path = "../../util/fastmap" }
 | 
			
		||||
failsafe = { version = "0.3.0", default-features = false, features = ["parking_lot_mutex"] }
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
smallvec = "1.2.0"
 | 
			
		||||
futures = "0.1"
 | 
			
		||||
rand = "0.7"
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ trie-db = "0.20.0"
 | 
			
		||||
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
 | 
			
		||||
registrar = { path = "../../util/registrar" }
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
rustc-hex = "1.0"
 | 
			
		||||
serde = "1.0"
 | 
			
		||||
serde_derive = "1.0"
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ rand = "0.7"
 | 
			
		||||
rand_xorshift = "0.2"
 | 
			
		||||
parking_lot = "0.10.0"
 | 
			
		||||
rlp = "0.4.2"
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
scopeguard = "1.0.0"
 | 
			
		||||
snappy = { package = "parity-snappy", version ="0.1.0" }
 | 
			
		||||
state-db = { path = "../state-db" }
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ parity-bytes = "0.1.0"
 | 
			
		||||
parity-util-mem = "0.5.1"
 | 
			
		||||
parking_lot = "0.10.0"
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
vm = { path = "../vm" }
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ parity-util-mem = "0.5.1"
 | 
			
		||||
parity-snappy = "0.1"
 | 
			
		||||
patricia-trie-ethereum = { path = "../../util/patricia-trie-ethereum" }
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
rlp_derive = { path = "../../util/rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
unexpected = { path = "../../util/unexpected" }
 | 
			
		||||
vm = { path = "../vm"}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ crc = "1"
 | 
			
		||||
ethereum-types = "0.8.0"
 | 
			
		||||
maplit = "1"
 | 
			
		||||
rlp = "0.4"
 | 
			
		||||
rlp_derive = { path = "../rlp-derive" }
 | 
			
		||||
rlp-derive = "0.1"
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
hex-literal = "0.2"
 | 
			
		||||
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "rlp_derive"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
authors = ["Parity Technologies <admin@parity.io>"]
 | 
			
		||||
edition = "2018"
 | 
			
		||||
 | 
			
		||||
[lib]
 | 
			
		||||
name = "rlp_derive"
 | 
			
		||||
proc-macro = true
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
syn = "1.0.14"
 | 
			
		||||
quote = "1.0.2"
 | 
			
		||||
proc-macro2 = "1.0.8"
 | 
			
		||||
 | 
			
		||||
[dev-dependencies]
 | 
			
		||||
rlp = "0.4.0"
 | 
			
		||||
@ -1,193 +0,0 @@
 | 
			
		||||
// 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
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 = match ast.data {
 | 
			
		||||
		syn::Data::Struct(ref s) => s,
 | 
			
		||||
		_ => 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<Self, rlp::DecoderError> {
 | 
			
		||||
				let result = #name {
 | 
			
		||||
					#(#stmts)*
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				Ok(result)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	quote! {
 | 
			
		||||
		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");
 | 
			
		||||
			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<Self, rlp::DecoderError> {
 | 
			
		||||
				let result = #name {
 | 
			
		||||
					#stmt
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				Ok(result)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	quote! {
 | 
			
		||||
		const _: () = {
 | 
			
		||||
			extern crate rlp;
 | 
			
		||||
			#impl_block
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 => {
 | 
			
		||||
			let index: syn::Index = index.into();
 | 
			
		||||
			quote! { #index }
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
				.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()?, }
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		_ => panic!("rlp_derive not supported"),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,134 +0,0 @@
 | 
			
		||||
// 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
use proc_macro2::TokenStream;
 | 
			
		||||
use quote::quote;
 | 
			
		||||
 | 
			
		||||
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(|(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 = 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 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 = 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.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");
 | 
			
		||||
						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"),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,52 +0,0 @@
 | 
			
		||||
// 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
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()
 | 
			
		||||
}
 | 
			
		||||
@ -1,79 +0,0 @@
 | 
			
		||||
// 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 <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
use rlp::{decode, encode};
 | 
			
		||||
use rlp_derive::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper};
 | 
			
		||||
 | 
			
		||||
#[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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_encode_foo_default() {
 | 
			
		||||
	#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
 | 
			
		||||
	struct FooDefault {
 | 
			
		||||
		a: String,
 | 
			
		||||
		/// It works with other attributes.
 | 
			
		||||
		#[rlp(default)]
 | 
			
		||||
		b: Option<Vec<u8>>,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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));
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user