mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 15:51:12 +00:00
Phase 1 of repo reorg (#719)
* Remove unneeded script * Rename Substrate Demo -> Substrate * Rename demo -> node * Build wasm from last rename. * Merge ed25519 into substrate-primitives * Minor tweak * Rename substrate -> core * Move substrate-runtime-support to core/runtime/support * Rename/move substrate-runtime-version * Move codec up a level * Rename substrate-codec -> parity-codec * Move environmental up a level * Move pwasm-* up to top, ready for removal * Remove requirement of s-r-support from s-r-primitives * Move core/runtime/primitives into core/runtime-primitives * Remove s-r-support dep from s-r-version * Remove dep of s-r-support from bft * Remove dep of s-r-support from node/consensus * Sever all other core deps from s-r-support * Forgot the no_std directive * Rename non-SRML modules to sr-* to avoid match clashes * Move runtime/* to srml/* * Rename substrate-runtime-* -> srml-* * Move srml to top-level
This commit is contained in:
committed by
Arkadiy Paronyan
parent
8fe5aa4c81
commit
1e01162505
@@ -0,0 +1,111 @@
|
||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate 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.
|
||||
|
||||
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use proc_macro2::{Span, TokenStream, Ident};
|
||||
use syn::{
|
||||
Data, Fields,
|
||||
spanned::Spanned,
|
||||
};
|
||||
|
||||
pub fn quote(data: &Data, type_name: &Ident, input: &TokenStream) -> TokenStream {
|
||||
let call_site = Span::call_site();
|
||||
match *data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(_) | Fields::Unnamed(_) => create_instance(
|
||||
call_site,
|
||||
quote! { #type_name },
|
||||
input,
|
||||
&data.fields,
|
||||
),
|
||||
Fields::Unit => {
|
||||
quote_spanned! {call_site =>
|
||||
drop(#input);
|
||||
Some(#type_name)
|
||||
}
|
||||
},
|
||||
},
|
||||
Data::Enum(ref data) => {
|
||||
assert!(data.variants.len() < 256, "Currently only enums with at most 256 variants are encodable.");
|
||||
|
||||
let recurse = data.variants.iter().enumerate().map(|(i, v)| {
|
||||
let name = &v.ident;
|
||||
let index = super::index(v, i);
|
||||
|
||||
let create = create_instance(
|
||||
call_site,
|
||||
quote! { #type_name :: #name },
|
||||
input,
|
||||
&v.fields,
|
||||
);
|
||||
|
||||
quote_spanned! { v.span() =>
|
||||
x if x == #index as u8 => {
|
||||
#create
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
match #input.read_byte()? {
|
||||
#( #recurse )*
|
||||
_ => None,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
Data::Union(_) => panic!("Union types are not supported."),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_instance(call_site: Span, name: TokenStream, input: &TokenStream, fields: &Fields) -> TokenStream {
|
||||
match *fields {
|
||||
Fields::Named(ref fields) => {
|
||||
let recurse = fields.named.iter().map(|f| {
|
||||
let name = &f.ident;
|
||||
let field = quote_spanned!(call_site => #name);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#field: ::codec::Decode::decode(#input)?
|
||||
}
|
||||
});
|
||||
|
||||
quote_spanned! {call_site =>
|
||||
Some(#name {
|
||||
#( #recurse, )*
|
||||
})
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(ref fields) => {
|
||||
let recurse = fields.unnamed.iter().map(|f| {
|
||||
quote_spanned! { f.span() =>
|
||||
::codec::Decode::decode(#input)?
|
||||
}
|
||||
});
|
||||
|
||||
quote_spanned! {call_site =>
|
||||
Some(#name (
|
||||
#( #recurse, )*
|
||||
))
|
||||
}
|
||||
},
|
||||
Fields::Unit => {
|
||||
quote_spanned! {call_site =>
|
||||
Some(#name)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate 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.
|
||||
|
||||
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use core::str::from_utf8;
|
||||
#[cfg(feature = "std")]
|
||||
use std::str::from_utf8;
|
||||
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use syn::{
|
||||
Data, Field, Fields, Ident, Index,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
token::Comma,
|
||||
};
|
||||
|
||||
type FieldsList = Punctuated<Field, Comma>;
|
||||
|
||||
fn encode_fields<F>(
|
||||
dest: &TokenStream,
|
||||
fields: &FieldsList,
|
||||
field_name: F,
|
||||
) -> TokenStream where
|
||||
F: Fn(usize, &Option<Ident>) -> TokenStream,
|
||||
{
|
||||
let recurse = fields.iter().enumerate().map(|(i, f)| {
|
||||
let field = field_name(i, &f.ident);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#dest.push(#field);
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#( #recurse )*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn quote(data: &Data, type_name: &Ident, self_: &TokenStream, dest: &TokenStream) -> TokenStream {
|
||||
let call_site = Span::call_site();
|
||||
match *data {
|
||||
Data::Struct(ref data) => match data.fields {
|
||||
Fields::Named(ref fields) => encode_fields(
|
||||
dest,
|
||||
&fields.named,
|
||||
|_, name| quote_spanned!(call_site => &#self_.#name),
|
||||
),
|
||||
Fields::Unnamed(ref fields) => encode_fields(
|
||||
dest,
|
||||
&fields.unnamed,
|
||||
|i, _| {
|
||||
let index = Index { index: i as u32, span: call_site };
|
||||
quote_spanned!(call_site => &#self_.#index)
|
||||
},
|
||||
),
|
||||
Fields::Unit => quote_spanned! { call_site =>
|
||||
drop(#dest);
|
||||
},
|
||||
},
|
||||
Data::Enum(ref data) => {
|
||||
assert!(data.variants.len() < 256, "Currently only enums with at most 256 variants are encodable.");
|
||||
|
||||
let recurse = data.variants.iter().enumerate().map(|(i, f)| {
|
||||
let name = &f.ident;
|
||||
let index = super::index(f, i);
|
||||
|
||||
match f.fields {
|
||||
Fields::Named(ref fields) => {
|
||||
let field_name = |_, ident: &Option<Ident>| quote_spanned!(call_site => #ident);
|
||||
let names = fields.named
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, f)| field_name(i, &f.ident));
|
||||
|
||||
let encode_fields = encode_fields(
|
||||
dest,
|
||||
&fields.named,
|
||||
|a, b| field_name(a, b),
|
||||
);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#type_name :: #name { #( ref #names, )* } => {
|
||||
#dest.push_byte(#index as u8);
|
||||
#encode_fields
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unnamed(ref fields) => {
|
||||
let field_name = |i, _: &Option<Ident>| {
|
||||
let data = stringify(i as u8);
|
||||
let ident = from_utf8(&data).expect("We never go beyond ASCII");
|
||||
let ident = Ident::new(ident, call_site);
|
||||
quote_spanned!(call_site => #ident)
|
||||
};
|
||||
let names = fields.unnamed
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, f)| field_name(i, &f.ident));
|
||||
|
||||
let encode_fields = encode_fields(
|
||||
dest,
|
||||
&fields.unnamed,
|
||||
|a, b| field_name(a, b),
|
||||
);
|
||||
|
||||
quote_spanned! { f.span() =>
|
||||
#type_name :: #name ( #( ref #names, )* ) => {
|
||||
#dest.push_byte(#index as u8);
|
||||
#encode_fields
|
||||
}
|
||||
}
|
||||
},
|
||||
Fields::Unit => {
|
||||
quote_spanned! { f.span() =>
|
||||
#type_name :: #name => {
|
||||
#dest.push_byte(#index as u8);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
match *#self_ {
|
||||
#( #recurse )*,
|
||||
}
|
||||
}
|
||||
},
|
||||
Data::Union(_) => panic!("Union types are not supported."),
|
||||
}
|
||||
}
|
||||
pub fn stringify(id: u8) -> [u8; 2] {
|
||||
const CHARS: &[u8] = b"abcdefghijklmnopqrstuvwxyz";
|
||||
let len = CHARS.len() as u8;
|
||||
let symbol = |id: u8| CHARS[(id % len) as usize];
|
||||
let a = symbol(id);
|
||||
let b = symbol(id / len);
|
||||
|
||||
[a, b]
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// Copyright 2018 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Substrate 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.
|
||||
|
||||
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Derives serialization and deserialization codec for complex structs for simple marshalling.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate proc_macro2;
|
||||
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::{DeriveInput, Generics, GenericParam, Ident};
|
||||
|
||||
mod decode;
|
||||
mod encode;
|
||||
|
||||
const ENCODE_ERR: &str = "derive(Encode) failed";
|
||||
|
||||
#[proc_macro_derive(Encode, attributes(codec))]
|
||||
pub fn encode_derive(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = syn::parse(input).expect(ENCODE_ERR);
|
||||
let name = &input.ident;
|
||||
|
||||
let generics = add_trait_bounds(input.generics, parse_quote!(::codec::Encode));
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let self_ = quote!(self);
|
||||
let dest_ = quote!(dest);
|
||||
let encoding = encode::quote(&input.data, name, &self_, &dest_);
|
||||
|
||||
let expanded = quote! {
|
||||
impl #impl_generics ::codec::Encode for #name #ty_generics #where_clause {
|
||||
fn encode_to<EncOut: ::codec::Output>(&#self_, #dest_: &mut EncOut) {
|
||||
#encoding
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(Decode, attributes(codec))]
|
||||
pub fn decode_derive(input: TokenStream) -> TokenStream {
|
||||
let input: DeriveInput = syn::parse(input).expect(ENCODE_ERR);
|
||||
let name = &input.ident;
|
||||
|
||||
let generics = add_trait_bounds(input.generics, parse_quote!(::codec::Decode));
|
||||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let input_ = quote!(input);
|
||||
let decoding = decode::quote(&input.data, name, &input_);
|
||||
|
||||
let expanded = quote! {
|
||||
impl #impl_generics ::codec::Decode for #name #ty_generics #where_clause {
|
||||
fn decode<DecIn: ::codec::Input>(#input_: &mut DecIn) -> Option<Self> {
|
||||
#decoding
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
fn add_trait_bounds(mut generics: Generics, bounds: syn::TypeParamBound) -> Generics {
|
||||
for param in &mut generics.params {
|
||||
if let GenericParam::Type(ref mut type_param) = *param {
|
||||
type_param.bounds.push(bounds.clone());
|
||||
}
|
||||
}
|
||||
generics
|
||||
}
|
||||
|
||||
fn index(v: &syn::Variant, i: usize) -> proc_macro2::TokenStream {
|
||||
// look for an index in attributes
|
||||
let index = v.attrs.iter().filter_map(|attr| {
|
||||
let pair = attr.path.segments.first()?;
|
||||
let seg = pair.value();
|
||||
|
||||
if seg.ident == Ident::new("codec", seg.ident.span()) {
|
||||
assert_eq!(attr.path.segments.len(), 1);
|
||||
|
||||
let meta = attr.interpret_meta();
|
||||
if let Some(syn::Meta::List(ref l)) = meta {
|
||||
if let syn::NestedMeta::Meta(syn::Meta::NameValue(ref nv)) = l.nested.last().unwrap().value() {
|
||||
assert_eq!(nv.ident, Ident::new("index", nv.ident.span()));
|
||||
if let syn::Lit::Str(ref s) = nv.lit {
|
||||
let byte: u8 = s.value().parse().expect("Numeric index expected.");
|
||||
return Some(byte)
|
||||
}
|
||||
panic!("Invalid syntax for `codec` attribute: Expected string literal.")
|
||||
}
|
||||
}
|
||||
panic!("Invalid syntax for `codec` attribute: Expected `name = value` pair.")
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).next();
|
||||
|
||||
// then fallback to discriminant or just index
|
||||
index.map(|i| quote! { #i })
|
||||
.unwrap_or_else(|| v.discriminant
|
||||
.as_ref()
|
||||
.map(|&(_, ref expr)| quote! { #expr })
|
||||
.unwrap_or_else(|| quote! { #i })
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user