mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 19:21:13 +00:00
decl_storage as a proc_macro (#1176)
* `decl_storage` parsing of the macro (TODO change tool crate structure) * Start formatting, for now use inner macro. Still missing optional formating last part (genesis ...). * Calling extra genesis macro * decl_storage lines parsing. * genesis macro as quote (need some cleaning reorg) * dirty $crate substitute * proc crate reorg. * PR impl : skip usage of phantom data, it only applies in test and council (others required it). * Remaining macro of decl_storage, warning stringify behave sometime oddly. * Formatting code and some cleaning. * Include line parsing to main struct (cannot use existing macro anymore). * Remove genesis phantom data when there is already a field with type parameter. * Revert wasm files * Remove old version of `decl_storage`. * Fix false positive for phantom trait (additional type check on config build). * slight changes: - return token errors instead of panic - do not use useless intermediate vec * Update srml/support/procedural/tools/derive/src/lib.rs remove indent Co-Authored-By: cheme <emericchevalier.pro@gmail.com> * Switch iterations to fold, remove unused import.
This commit is contained in:
Generated
+46
-14
@@ -703,7 +703,7 @@ name = "failure_derive"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1597,7 +1597,7 @@ version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2032,7 +2032,7 @@ name = "parity-codec-derive"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2172,7 +2172,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.23"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2236,7 +2236,7 @@ name = "quote"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2602,7 +2602,7 @@ name = "serde_derive"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -2712,7 +2712,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec-derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-primitives 0.1.0",
|
||||
@@ -3013,6 +3013,37 @@ dependencies = [
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"srml-metadata 0.1.0",
|
||||
"srml-support-procedural 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-api-macros 0.1.0",
|
||||
"srml-support-procedural-tools 0.1.0",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural-tools"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"srml-support-procedural-tools-derive 0.1.0",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural-tools-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3077,6 +3108,7 @@ dependencies = [
|
||||
"sr-std 0.1.0",
|
||||
"srml-consensus 0.1.0",
|
||||
"srml-support 0.1.0",
|
||||
"srml-support-procedural 0.1.0",
|
||||
"srml-system 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
@@ -3113,7 +3145,7 @@ name = "stdweb-derive"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3126,7 +3158,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base-x 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3173,7 +3205,7 @@ version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"heck 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -3759,7 +3791,7 @@ name = "syn"
|
||||
version = "0.14.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -3769,7 +3801,7 @@ name = "syn"
|
||||
version = "0.15.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -3779,7 +3811,7 @@ name = "synstructure"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -4768,7 +4800,7 @@ dependencies = [
|
||||
"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
|
||||
"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
|
||||
"checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7"
|
||||
"checksum proc-macro2 0.4.23 (registry+https://github.com/rust-lang/crates.io-index)" = "88dae56b29da695d783ea7fc5a90de281f79eb38407e77f6d674dd8befc4ac47"
|
||||
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
||||
"checksum protobuf 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "671a9cce836bd3635b40b2b0a72783481755ee988c493891f4e974b45264cc9d"
|
||||
"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5"
|
||||
"checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
|
||||
|
||||
@@ -40,6 +40,9 @@ members = [
|
||||
"core/transaction-pool",
|
||||
"core/transaction-pool/graph",
|
||||
"srml/support",
|
||||
"srml/support/procedural",
|
||||
"srml/support/procedural/tools",
|
||||
"srml/support/procedural/tools/derive",
|
||||
"srml/assets",
|
||||
"srml/balances",
|
||||
"srml/consensus",
|
||||
|
||||
+43
-13
@@ -395,7 +395,7 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -559,8 +559,8 @@ name = "parity-codec-derive"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -638,7 +638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.19"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -646,10 +646,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.8"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -918,6 +918,36 @@ dependencies = [
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"srml-metadata 0.1.0",
|
||||
"srml-support-procedural 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"srml-support-procedural-tools 0.1.0",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural-tools"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"srml-support-procedural-tools-derive 0.1.0",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural-tools-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -981,7 +1011,7 @@ dependencies = [
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
@@ -1098,8 +1128,8 @@ name = "syn"
|
||||
version = "0.14.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1108,8 +1138,8 @@ name = "syn"
|
||||
version = "0.15.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1531,8 +1561,8 @@ dependencies = [
|
||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||
"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
|
||||
"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
|
||||
"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901"
|
||||
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
||||
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
||||
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
||||
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
|
||||
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
|
||||
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
|
||||
|
||||
@@ -59,7 +59,6 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
consensus: Some(ConsensusConfig {
|
||||
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(), // TODO change
|
||||
authorities: initial_authorities.clone(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
system: None,
|
||||
balances: Some(BalancesConfig {
|
||||
@@ -70,12 +69,10 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
transfer_fee: 1 * CENTS,
|
||||
creation_fee: 1 * CENTS,
|
||||
reclaim_rebate: 1 * CENTS,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
|
||||
session_length: 5 * MINUTES,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
current_era: 0,
|
||||
@@ -89,13 +86,11 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
bonding_duration: 1 * DAYS,
|
||||
offline_slash_grace: 4,
|
||||
minimum_validator_count: 4,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
democracy: Some(DemocracyConfig {
|
||||
launch_period: 5 * MINUTES, // 1 day per public referendum
|
||||
voting_period: 5 * MINUTES, // 3 days to discuss & vote on an active referendum
|
||||
minimum_deposit: 50 * DOLLARS, // 12000 as the minimum deposit for a referendum
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
council_seats: Some(CouncilSeatsConfig {
|
||||
active_council: vec![],
|
||||
@@ -108,23 +103,19 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
term_duration: 28 * DAYS,
|
||||
desired_seats: 0,
|
||||
inactive_grace_period: 1, // one additional vote should go by before an inactive voter can be reaped.
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
council_voting: Some(CouncilVotingConfig {
|
||||
cooloff_period: 4 * DAYS,
|
||||
voting_period: 1 * DAYS,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
timestamp: Some(TimestampConfig {
|
||||
period: SECS_PER_BLOCK,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
treasury: Some(TreasuryConfig {
|
||||
proposal_bond: Permill::from_percent(5),
|
||||
proposal_bond_minimum: 1 * DOLLARS,
|
||||
spend_period: 1 * DAYS,
|
||||
burn: Permill::from_percent(50),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
contract: Some(ContractConfig {
|
||||
contract_fee: 1 * CENTS,
|
||||
@@ -134,15 +125,12 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
max_depth: 1024,
|
||||
block_gas_limit: 10_000_000,
|
||||
current_schedule: Default::default(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
upgrade_key: Some(UpgradeKeyConfig {
|
||||
key: endowed_accounts[0].clone(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
grandpa: Some(GrandpaConfig {
|
||||
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -190,7 +178,6 @@ pub fn testnet_genesis(
|
||||
consensus: Some(ConsensusConfig {
|
||||
code: include_bytes!("../../runtime/wasm/target/wasm32-unknown-unknown/release/node_runtime.compact.wasm").to_vec(),
|
||||
authorities: initial_authorities.clone(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
system: None,
|
||||
balances: Some(BalancesConfig {
|
||||
@@ -201,12 +188,10 @@ pub fn testnet_genesis(
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
balances: endowed_accounts.iter().map(|&k| (k.into(), (1 << 60))).collect(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
validators: initial_authorities.iter().cloned().map(Into::into).collect(),
|
||||
session_length: 10,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
current_era: 0,
|
||||
@@ -220,13 +205,11 @@ pub fn testnet_genesis(
|
||||
current_offline_slash: 0,
|
||||
current_session_reward: 0,
|
||||
offline_slash_grace: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
democracy: Some(DemocracyConfig {
|
||||
launch_period: 9,
|
||||
voting_period: 18,
|
||||
minimum_deposit: 10,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
council_seats: Some(CouncilSeatsConfig {
|
||||
active_council: endowed_accounts.iter()
|
||||
@@ -241,23 +224,19 @@ pub fn testnet_genesis(
|
||||
term_duration: 1000000,
|
||||
desired_seats: (endowed_accounts.len() - initial_authorities.len()) as u32,
|
||||
inactive_grace_period: 1,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
council_voting: Some(CouncilVotingConfig {
|
||||
cooloff_period: 75,
|
||||
voting_period: 20,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
timestamp: Some(TimestampConfig {
|
||||
period: 5, // 5 second block time.
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
treasury: Some(TreasuryConfig {
|
||||
proposal_bond: Permill::from_percent(5),
|
||||
proposal_bond_minimum: 1_000_000,
|
||||
spend_period: 12 * 60 * 24,
|
||||
burn: Permill::from_percent(50),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
contract: Some(ContractConfig {
|
||||
contract_fee: 21,
|
||||
@@ -267,15 +246,12 @@ pub fn testnet_genesis(
|
||||
max_depth: 1024,
|
||||
block_gas_limit: 10_000_000,
|
||||
current_schedule: Default::default(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
upgrade_key: Some(UpgradeKeyConfig {
|
||||
key: upgrade_key,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
grandpa: Some(GrandpaConfig {
|
||||
authorities: initial_authorities.clone().into_iter().map(|k| (k, 1)).collect(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -319,7 +295,7 @@ mod tests {
|
||||
|
||||
fn local_testnet_genesis_instant() -> GenesisConfig {
|
||||
let mut genesis = local_testnet_genesis();
|
||||
genesis.timestamp = Some(TimestampConfig { period: 0, _genesis_phantom_data: Default::default() });
|
||||
genesis.timestamp = Some(TimestampConfig { period: 0 });
|
||||
genesis
|
||||
}
|
||||
|
||||
|
||||
@@ -235,12 +235,10 @@ mod tests {
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
session: Some(SessionConfig {
|
||||
session_length: 2,
|
||||
validators: vec![One.to_raw_public().into(), Two.to_raw_public().into(), three],
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
staking: Some(StakingConfig {
|
||||
sessions_per_era: 2,
|
||||
@@ -254,7 +252,6 @@ mod tests {
|
||||
current_offline_slash: 0,
|
||||
current_session_reward: 0,
|
||||
offline_slash_grace: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
democracy: Some(Default::default()),
|
||||
council_seats: Some(Default::default()),
|
||||
@@ -269,7 +266,6 @@ mod tests {
|
||||
(Bob.to_raw_public().into(), 1),
|
||||
(Charlie.to_raw_public().into(), 1),
|
||||
],
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}),
|
||||
}.build_storage().unwrap().0)
|
||||
}
|
||||
|
||||
Generated
+44
-13
@@ -395,7 +395,7 @@ version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -602,8 +602,8 @@ name = "parity-codec-derive"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -681,7 +681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.19"
|
||||
version = "0.4.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -699,10 +699,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.8"
|
||||
version = "0.6.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1155,6 +1155,36 @@ dependencies = [
|
||||
"sr-primitives 0.1.0",
|
||||
"sr-std 0.1.0",
|
||||
"srml-metadata 0.1.0",
|
||||
"srml-support-procedural 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"srml-support-procedural-tools 0.1.0",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural-tools"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"srml-support-procedural-tools-derive 0.1.0",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "srml-support-procedural-tools-derive"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1219,6 +1249,7 @@ dependencies = [
|
||||
"sr-std 0.1.0",
|
||||
"srml-consensus 0.1.0",
|
||||
"srml-support 0.1.0",
|
||||
"srml-support-procedural 0.1.0",
|
||||
"srml-system 0.1.0",
|
||||
"substrate-primitives 0.1.0",
|
||||
]
|
||||
@@ -1284,7 +1315,7 @@ dependencies = [
|
||||
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-codec 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sr-io 0.1.0",
|
||||
@@ -1396,8 +1427,8 @@ name = "syn"
|
||||
version = "0.14.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1406,8 +1437,8 @@ name = "syn"
|
||||
version = "0.15.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1829,9 +1860,9 @@ dependencies = [
|
||||
"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
|
||||
"checksum proc-macro-hack 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2c725b36c99df7af7bf9324e9c999b9e37d92c8f8caf106d82e1d7953218d2d8"
|
||||
"checksum proc-macro-hack-impl 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2b753ad9ed99dd8efeaa7d2fb8453c8f6bc3e54b97966d35f1bc77ca6865254a"
|
||||
"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901"
|
||||
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
||||
"checksum pwasm-utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd695333cfae6e9dbe2703a6d040e252b57a6fc3b9a65c712615ac042b2e0c5"
|
||||
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
|
||||
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
||||
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
|
||||
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
|
||||
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
|
||||
|
||||
@@ -104,7 +104,6 @@ impl ExtBuilder {
|
||||
transfer_fee: self.transfer_fee,
|
||||
creation_fee: self.creation_fee,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ pub fn new_test_ext(authorities: Vec<u64>) -> runtime_io::TestExternalities<Blak
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
@@ -131,7 +131,6 @@ impl ExtBuilder {
|
||||
transfer_fee: self.transfer_fee,
|
||||
creation_fee: self.creation_fee,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage()
|
||||
.unwrap().0,
|
||||
);
|
||||
@@ -144,7 +143,6 @@ impl ExtBuilder {
|
||||
max_depth: 100,
|
||||
block_gas_limit: self.block_gas_limit,
|
||||
current_schedule: Default::default(),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage()
|
||||
.unwrap().0,
|
||||
);
|
||||
|
||||
@@ -122,13 +122,11 @@ mod tests {
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(democracy::GenesisConfig::<Test>{
|
||||
launch_period: 1,
|
||||
voting_period: 3,
|
||||
minimum_deposit: 1,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(seats::GenesisConfig::<Test> {
|
||||
candidacy_bond: 9,
|
||||
@@ -145,12 +143,10 @@ mod tests {
|
||||
presentation_duration: 2,
|
||||
desired_seats: 2,
|
||||
term_duration: 5,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(voting::GenesisConfig::<Test> {
|
||||
cooloff_period: 2,
|
||||
voting_period: 1,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
runtime_io::TestExternalities::new(t)
|
||||
}
|
||||
|
||||
@@ -172,7 +172,6 @@ decl_storage! {
|
||||
pub ProposalCount get(proposal_count): u32;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(_marker): ::std::marker::PhantomData<T>;
|
||||
build(|_, _, _| {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,13 +358,11 @@ mod tests {
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
launch_period: 1,
|
||||
voting_period: 1,
|
||||
minimum_deposit: 1,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
runtime_io::TestExternalities::new(t)
|
||||
}
|
||||
|
||||
@@ -313,7 +313,6 @@ mod tests {
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
dummy: 42,
|
||||
foo: 24,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
@@ -327,7 +327,6 @@ mod tests {
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
let xt = primitives::testing::TestXt(Some(1), 0, Call::transfer(2.into(), 69.into()));
|
||||
let mut t = runtime_io::TestExternalities::<Blake2Hasher>::new(t);
|
||||
|
||||
@@ -69,7 +69,6 @@ impl_outer_event!{
|
||||
pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternalities<Blake2Hasher> {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
_genesis_phantom_data: Default::default(),
|
||||
authorities,
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
|
||||
@@ -296,16 +296,13 @@ mod tests {
|
||||
t.extend(consensus::GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities: vec![1, 2, 3],
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(timestamp::GenesisConfig::<Test>{
|
||||
period: 5,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
session_length: 2,
|
||||
validators: vec![1, 2, 3],
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
runtime_io::TestExternalities::new(t)
|
||||
}
|
||||
|
||||
@@ -88,12 +88,10 @@ pub fn new_test_ext(
|
||||
t.extend(consensus::GenesisConfig::<Test>{
|
||||
code: vec![],
|
||||
authorities: vec![],
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(session::GenesisConfig::<Test>{
|
||||
session_length,
|
||||
validators: vec![10, 20],
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(balances::GenesisConfig::<Test>{
|
||||
balances: if monied {
|
||||
@@ -111,7 +109,6 @@ pub fn new_test_ext(
|
||||
transfer_fee: 0,
|
||||
creation_fee: 0,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
sessions_per_era,
|
||||
@@ -125,11 +122,9 @@ pub fn new_test_ext(
|
||||
current_session_reward: reward,
|
||||
current_offline_slash: 20,
|
||||
offline_slash_grace: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(timestamp::GenesisConfig::<Test>{
|
||||
period: 5,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
runtime_io::TestExternalities::new(t)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ srml-metadata = { path = "../metadata", default-features = false }
|
||||
sr-std = { path = "../../core/sr-std", default-features = false }
|
||||
sr-io = { path = "../../core/sr-io", default-features = false }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
srml-support-procedural = { path = "./procedural" }
|
||||
mashup = "0.1.7"
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "srml-support-procedural"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
srml-support-procedural-tools = { path = "./tools" }
|
||||
sr-api-macros = { path = "../../../core/sr-api-macros" }
|
||||
|
||||
proc-macro2 = "0.4"
|
||||
quote = { version = "0.6" }
|
||||
syn = { version = "0.15", features = ["full"] }
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
// tag::description[]
|
||||
//! Proc macro of Support code for the runtime.
|
||||
// end::description[]
|
||||
|
||||
#![recursion_limit="256"]
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate proc_macro2;
|
||||
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
#[macro_use]
|
||||
extern crate srml_support_procedural_tools;
|
||||
|
||||
mod storage;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
/// Declares strongly-typed wrappers around codec-compatible types in storage.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```compile_fail
|
||||
/// decl_storage! {
|
||||
/// trait Store for Module<T: Trait> as Example {
|
||||
/// Dummy get(dummy) config(): Option<T::Balance>;
|
||||
/// Foo get(foo) config(): T::Balance;
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// For now we implement a convenience trait with pre-specialised associated types, one for each
|
||||
/// storage item. This allows you to gain access to publicly visible storage items from a
|
||||
/// module type. Currently you must disambiguate by using `<Module as Store>::Item` rather than
|
||||
/// the simpler `Module::Item`. Hopefully the rust guys with fix this soon.
|
||||
#[proc_macro]
|
||||
pub fn decl_storage(input: TokenStream) -> TokenStream {
|
||||
storage::transformation::decl_storage_impl(input)
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
// tag::description[]
|
||||
//! `decl_storage` macro
|
||||
// end::description[]
|
||||
|
||||
use srml_support_procedural_tools::syn_ext as ext;
|
||||
|
||||
use syn::Ident;
|
||||
use syn::token::CustomKeyword;
|
||||
|
||||
pub mod transformation;
|
||||
|
||||
/// Parsing usage only
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct StorageDefinition {
|
||||
pub hidden_crate: Option<SpecificHiddenCrate>,
|
||||
pub visibility: syn::Visibility,
|
||||
pub trait_token: Token![trait],
|
||||
pub ident: Ident,
|
||||
pub for_token: Token![for],
|
||||
pub module_ident: Ident,
|
||||
pub mod_lt_token: Token![<],
|
||||
pub mod_param: syn::GenericParam,
|
||||
pub mod_gt_token: Token![>],
|
||||
pub as_token: Token![as],
|
||||
pub crate_ident: Ident,
|
||||
pub content: ext::Braces<ext::Punctuated<DeclStorageLine, Token![;]>>,
|
||||
pub extra_genesis: Option<AddExtraGenesis>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct SpecificHiddenCrate {
|
||||
pub keyword: ext::CustomToken<SpecificHiddenCrate>,
|
||||
pub ident: ext::Parens<Ident>,
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct AddExtraGenesis {
|
||||
pub extragenesis_keyword: ext::CustomToken<AddExtraGenesis>,
|
||||
pub content: ext::Braces<AddExtraGenesisContent>,
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct AddExtraGenesisContent {
|
||||
pub lines: ext::Punctuated<AddExtraGenesisLineEnum, Token![;]>,
|
||||
}
|
||||
|
||||
#[derive(ParseEnum, ToTokensEnum, Debug)]
|
||||
enum AddExtraGenesisLineEnum {
|
||||
AddExtraGenesisLine(AddExtraGenesisLine),
|
||||
AddExtraGenesisBuild(DeclStorageBuild),
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct AddExtraGenesisLine {
|
||||
pub attrs: ext::OuterAttributes,
|
||||
pub config_keyword: ext::CustomToken<ConfigKeyword>,
|
||||
pub extra_field: ext::Parens<Ident>,
|
||||
pub coldot_token: Token![:],
|
||||
pub extra_type: syn::Type,
|
||||
// TODO use a custom ext::Option instead (syn option on '=' fails)
|
||||
pub default_value: ext::Seq<DeclStorageDefault>,
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct DeclStorageLine {
|
||||
// attrs (main use case is doc)
|
||||
pub attrs: ext::OuterAttributes,
|
||||
// visibility (no need to make optional
|
||||
pub visibility: syn::Visibility,
|
||||
// name
|
||||
pub name: Ident,
|
||||
pub getter: Option<DeclStorageGetter>,
|
||||
pub config: Option<DeclStorageConfig>,
|
||||
pub build: Option<DeclStorageBuild>,
|
||||
pub coldot_token: Token![:],
|
||||
pub storage_type: DeclStorageType,
|
||||
// TODO use a custom ext::Option instead (syn option on '=' fails)
|
||||
pub default_value: ext::Seq<DeclStorageDefault>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct DeclStorageGetter {
|
||||
pub getter_keyword: ext::CustomToken<DeclStorageGetter>,
|
||||
pub getfn: ext::Parens<Ident>,
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct DeclStorageConfig {
|
||||
pub config_keyword: ext::CustomToken<DeclStorageConfig>,
|
||||
pub expr: ext::Parens<Option<syn::Ident>>,
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct DeclStorageBuild {
|
||||
pub build_keyword: ext::CustomToken<DeclStorageBuild>,
|
||||
pub expr: ext::Parens<syn::Expr>,
|
||||
}
|
||||
|
||||
#[derive(ParseEnum, ToTokensEnum, Debug)]
|
||||
enum DeclStorageType {
|
||||
Map(DeclStorageMap),
|
||||
Simple(syn::Type),
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct DeclStorageMap {
|
||||
pub map_keyword: ext::CustomToken<MapKeyword>,
|
||||
pub key: syn::Type,
|
||||
pub ass_keyword: Token![=>],
|
||||
pub value: syn::Type,
|
||||
}
|
||||
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
struct DeclStorageDefault {
|
||||
pub equal_token: Token![=],
|
||||
pub expr: syn::Expr,
|
||||
}
|
||||
|
||||
custom_keyword_impl!(SpecificHiddenCrate, "hiddencrate", "hiddencrate as keyword");
|
||||
custom_keyword_impl!(DeclStorageConfig, "config", "build as keyword");
|
||||
custom_keyword!(ConfigKeyword, "config", "config as keyword");
|
||||
custom_keyword!(BuildKeyword, "build", "build as keyword");
|
||||
custom_keyword_impl!(DeclStorageBuild, "build", "storage build config");
|
||||
custom_keyword_impl!(AddExtraGenesis, "add_extra_genesis", "storage extra genesis");
|
||||
custom_keyword_impl!(DeclStorageGetter, "get", "storage getter");
|
||||
custom_keyword!(MapKeyword, "map", "map as keyword");
|
||||
@@ -0,0 +1,636 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
// tag::description[]
|
||||
//! `decl_storage` macro transformation
|
||||
// end::description[]
|
||||
|
||||
use srml_support_procedural_tools::syn_ext as ext;
|
||||
use srml_support_procedural_tools::{generate_crate_access, generate_hidden_includes};
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
|
||||
use syn::{
|
||||
Ident,
|
||||
GenericParam,
|
||||
spanned::Spanned,
|
||||
parse::{
|
||||
Error,
|
||||
Result,
|
||||
}
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
// try macro but returning tokenized error
|
||||
macro_rules! try_tok(( $expre : expr ) => {
|
||||
match $expre {
|
||||
Ok(r) => r,
|
||||
Err (err) => {
|
||||
return err.to_compile_error().into()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pub fn decl_storage_impl(input: TokenStream) -> TokenStream {
|
||||
let def = parse_macro_input!(input as StorageDefinition);
|
||||
|
||||
// old macro naming convention (s replaces $)
|
||||
let StorageDefinition {
|
||||
hidden_crate,
|
||||
visibility,
|
||||
ident: storetype,
|
||||
module_ident,
|
||||
mod_param: strait,
|
||||
crate_ident: cratename,
|
||||
content: ext::Braces { content: storage_lines, ..},
|
||||
extra_genesis,
|
||||
..
|
||||
} = def;
|
||||
let hidden_crate_name = hidden_crate.map(|rc| rc.ident.content).map(|i| i.to_string())
|
||||
.unwrap_or_else(|| "decl_storage".to_string());
|
||||
let scrate = generate_crate_access(&hidden_crate_name, "srml-support");
|
||||
let scrate_decl = generate_hidden_includes(
|
||||
&hidden_crate_name,
|
||||
"srml-support",
|
||||
"srml_support",
|
||||
);
|
||||
|
||||
let (
|
||||
traitinstance,
|
||||
traittypes,
|
||||
) = if let GenericParam::Type(syn::TypeParam {ident, bounds, ..}) = strait {
|
||||
(ident, bounds)
|
||||
} else {
|
||||
return try_tok!(Err(Error::new(strait.span(), "Missing declare store generic params")));
|
||||
};
|
||||
|
||||
let traittype = if let Some(traittype) = traittypes.first() {
|
||||
traittype.into_value()
|
||||
} else {
|
||||
return try_tok!(Err(Error::new(traittypes.span(), "Trait bound expected")));
|
||||
};
|
||||
|
||||
let extra_genesis = try_tok!(decl_store_extra_genesis(
|
||||
&scrate,
|
||||
&traitinstance,
|
||||
&traittype,
|
||||
&storage_lines,
|
||||
&extra_genesis,
|
||||
));
|
||||
let decl_storage_items = decl_storage_items(
|
||||
&scrate,
|
||||
&traitinstance,
|
||||
&traittype,
|
||||
&cratename,
|
||||
&storage_lines,
|
||||
);
|
||||
let decl_store_items = decl_store_items(
|
||||
&storage_lines,
|
||||
);
|
||||
let impl_store_items = impl_store_items(
|
||||
&traitinstance,
|
||||
&storage_lines,
|
||||
);
|
||||
let impl_store_fns = impl_store_fns(
|
||||
&scrate,
|
||||
&traitinstance,
|
||||
&storage_lines,
|
||||
);
|
||||
let store_functions_to_metadata = store_functions_to_metadata(
|
||||
&scrate,
|
||||
&storage_lines,
|
||||
);
|
||||
let cratename_string = cratename.to_string();
|
||||
let expanded = quote! {
|
||||
#scrate_decl
|
||||
#decl_storage_items
|
||||
#visibility trait #storetype {
|
||||
#decl_store_items
|
||||
}
|
||||
impl<#traitinstance: #traittype> #storetype for #module_ident<#traitinstance> {
|
||||
#impl_store_items
|
||||
}
|
||||
impl<#traitinstance: #traittype> #module_ident<#traitinstance> {
|
||||
#impl_store_fns
|
||||
pub fn store_metadata() -> #scrate::storage::generator::StorageMetadata {
|
||||
#scrate::storage::generator::StorageMetadata {
|
||||
prefix: #scrate::storage::generator::DecodeDifferent::Encode(#cratename_string),
|
||||
functions: #store_functions_to_metadata ,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#extra_genesis
|
||||
|
||||
};
|
||||
|
||||
expanded.into()
|
||||
}
|
||||
|
||||
fn decl_store_extra_genesis(
|
||||
scrate: &TokenStream2,
|
||||
traitinstance: &Ident,
|
||||
traittype: &syn::TypeParamBound,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
extra_genesis: &Option<AddExtraGenesis>,
|
||||
) -> Result<TokenStream2> {
|
||||
|
||||
let mut is_trait_needed = false;
|
||||
let mut has_trait_field = false;
|
||||
let mut config_field = TokenStream2::new();
|
||||
let mut config_field_default = TokenStream2::new();
|
||||
let mut builders = TokenStream2::new();
|
||||
for sline in storage_lines.inner.iter() {
|
||||
|
||||
let DeclStorageLine {
|
||||
name,
|
||||
getter,
|
||||
config,
|
||||
build,
|
||||
storage_type,
|
||||
default_value,
|
||||
..
|
||||
} = sline;
|
||||
|
||||
let is_simple = if let DeclStorageType::Simple(..) = storage_type { true } else { false };
|
||||
|
||||
let mut opt_build;
|
||||
// need build line
|
||||
if let (Some(ref getter), Some(ref config)) = (getter, config) {
|
||||
let ident = if let Some(ident) = config.expr.content.as_ref() {
|
||||
quote!( #ident )
|
||||
} else {
|
||||
let ident = &getter.getfn.content;
|
||||
quote!( #ident )
|
||||
};
|
||||
let option_extracteed = if let DeclStorageType::Simple(ref st) = storage_type {
|
||||
if ext::has_parametric_type(st, traitinstance) {
|
||||
is_trait_needed = true;
|
||||
has_trait_field = true;
|
||||
}
|
||||
ext::extract_type_option(st)
|
||||
} else { None };
|
||||
let is_option = option_extracteed.is_some();
|
||||
let storage_type = option_extracteed.unwrap_or_else(|| quote!( #storage_type ));
|
||||
config_field.extend(quote!( pub #ident: #storage_type, ));
|
||||
opt_build = Some(build.as_ref().map(|b| &b.expr.content).map(|b|quote!( #b ))
|
||||
.unwrap_or_else(|| quote!( (|config: &GenesisConfig<#traitinstance>| config.#ident.clone()) )));
|
||||
let fielddefault = default_value.inner.get(0).as_ref().map(|d| &d.expr).map(|d|
|
||||
if is_option {
|
||||
quote!( #d.unwrap_or_default() )
|
||||
} else {
|
||||
quote!( #d )
|
||||
}).unwrap_or_else(|| quote!( Default::default() ));
|
||||
config_field_default.extend(quote!( #ident: #fielddefault, ));
|
||||
|
||||
} else {
|
||||
opt_build = build.as_ref().map(|b| &b.expr.content).map(|b| quote!( #b ));
|
||||
}
|
||||
|
||||
if let Some(builder) = opt_build {
|
||||
is_trait_needed = true;
|
||||
if is_simple {
|
||||
builders.extend(quote!{{
|
||||
use #scrate::codec::Encode;
|
||||
let v = (#builder)(&self);
|
||||
r.insert(Self::hash(<#name<#traitinstance>>::key()).to_vec(), v.encode());
|
||||
}});
|
||||
} else {
|
||||
builders.extend(quote!{{
|
||||
use #scrate::codec::Encode;
|
||||
let data = (#builder)(&self);
|
||||
for (k, v) in data.into_iter() {
|
||||
r.insert(Self::hash(&<#name<#traitinstance>>::key_for(k)).to_vec(), v.encode());
|
||||
}
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let mut has_scall = false;
|
||||
let mut scall = quote!{ ( |_, _, _| {} ) };
|
||||
let mut genesis_extrafields = TokenStream2::new();
|
||||
let mut genesis_extrafields_default = TokenStream2::new();
|
||||
|
||||
// extra genesis
|
||||
if let Some(eg) = extra_genesis {
|
||||
for ex_content in eg.content.content.lines.inner.iter() {
|
||||
match ex_content {
|
||||
AddExtraGenesisLineEnum::AddExtraGenesisLine(AddExtraGenesisLine {
|
||||
attrs,
|
||||
extra_field,
|
||||
extra_type,
|
||||
default_value,
|
||||
..
|
||||
}) => {
|
||||
if ext::has_parametric_type(&extra_type, traitinstance) {
|
||||
is_trait_needed = true;
|
||||
has_trait_field = true;
|
||||
}
|
||||
let extrafield = &extra_field.content;
|
||||
genesis_extrafields.extend(quote!{
|
||||
#attrs pub #extrafield: #extra_type,
|
||||
});
|
||||
let extra_default = default_value.inner.get(0).map(|d| &d.expr).map(|e| quote!{ #e })
|
||||
.unwrap_or_else(|| quote!( Default::default() ));
|
||||
genesis_extrafields_default.extend(quote!{
|
||||
#extrafield: #extra_default,
|
||||
});
|
||||
},
|
||||
AddExtraGenesisLineEnum::AddExtraGenesisBuild(DeclStorageBuild{ expr, .. }) => {
|
||||
if has_scall {
|
||||
return Err(Error::new(expr.span(), "Only one build expression allowed for extra genesis"));
|
||||
}
|
||||
let content = &expr.content;
|
||||
scall = quote!( ( #content ) );
|
||||
has_scall = true;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let is_extra_genesis_needed = has_scall
|
||||
|| !config_field.is_empty()
|
||||
|| !genesis_extrafields.is_empty()
|
||||
|| !builders.is_empty();
|
||||
Ok(if is_extra_genesis_needed {
|
||||
let (fparam, sparam, ph_field, ph_default) = if is_trait_needed {
|
||||
if has_trait_field {
|
||||
// no phantom data required
|
||||
(
|
||||
quote!(<#traitinstance: #traittype>),
|
||||
quote!(<#traitinstance>),
|
||||
quote!(),
|
||||
quote!(),
|
||||
)
|
||||
} else {
|
||||
// need phantom data
|
||||
(
|
||||
quote!(<#traitinstance: #traittype>),
|
||||
quote!(<#traitinstance>),
|
||||
|
||||
quote!{
|
||||
#[serde(skip)]
|
||||
pub _genesis_phantom_data: #scrate::storage::generator::PhantomData<#traitinstance>,
|
||||
},
|
||||
quote!{
|
||||
_genesis_phantom_data: Default::default(),
|
||||
},
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// do not even need type parameter
|
||||
(quote!(), quote!(), quote!(), quote!())
|
||||
};
|
||||
quote!{
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[cfg(feature = "std")]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct GenesisConfig#fparam {
|
||||
#ph_field
|
||||
#config_field
|
||||
#genesis_extrafields
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl#fparam Default for GenesisConfig#sparam {
|
||||
fn default() -> Self {
|
||||
GenesisConfig {
|
||||
#ph_default
|
||||
#config_field_default
|
||||
#genesis_extrafields_default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl#fparam #scrate::runtime_primitives::BuildStorage for GenesisConfig#sparam {
|
||||
|
||||
fn build_storage(self) -> ::std::result::Result<(#scrate::runtime_primitives::StorageMap, #scrate::runtime_primitives::ChildrenStorageMap), String> {
|
||||
let mut r: #scrate::runtime_primitives::StorageMap = Default::default();
|
||||
let mut c: #scrate::runtime_primitives::ChildrenStorageMap = Default::default();
|
||||
|
||||
#builders
|
||||
|
||||
#scall(&mut r, &mut c, &self);
|
||||
|
||||
Ok((r, c))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote!()
|
||||
})
|
||||
}
|
||||
|
||||
fn decl_storage_items(
|
||||
scrate: &TokenStream2,
|
||||
traitinstance: &Ident,
|
||||
traittype: &syn::TypeParamBound,
|
||||
cratename: &Ident,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
) -> TokenStream2 {
|
||||
|
||||
let mut impls = TokenStream2::new();
|
||||
for sline in storage_lines.inner.iter() {
|
||||
let DeclStorageLine {
|
||||
name,
|
||||
storage_type,
|
||||
default_value,
|
||||
visibility,
|
||||
..
|
||||
} = sline;
|
||||
|
||||
let (is_simple, extracted_opt, stk, gettype) = match storage_type {
|
||||
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
|
||||
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
|
||||
};
|
||||
let is_option = extracted_opt.is_some();
|
||||
let fielddefault = default_value.inner.get(0).as_ref().map(|d| &d.expr).map(|d| quote!( #d ))
|
||||
.unwrap_or_else(|| quote!{ Default::default() });
|
||||
|
||||
let typ = extracted_opt.unwrap_or(quote!( #gettype ));
|
||||
|
||||
let option_simple_1 = if !is_option {
|
||||
// raw type case
|
||||
quote!( unwrap_or_else )
|
||||
} else {
|
||||
// Option<> type case
|
||||
quote!( or_else )
|
||||
};
|
||||
let implementation = if is_simple {
|
||||
let mutate_impl = if !is_option {
|
||||
quote!{
|
||||
<Self as #scrate::storage::generator::StorageValue<#typ>>::put(&val, storage)
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
match val {
|
||||
Some(ref val) => <Self as #scrate::storage::generator::StorageValue<#typ>>::put(&val, storage),
|
||||
None => <Self as #scrate::storage::generator::StorageValue<#typ>>::kill(storage),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let key_string = cratename.to_string() + " " + &name.to_string();
|
||||
// generator for value
|
||||
quote!{
|
||||
|
||||
#visibility struct #name<#traitinstance: #traittype>(#scrate::storage::generator::PhantomData<#traitinstance>);
|
||||
|
||||
impl<#traitinstance: #traittype> #scrate::storage::generator::StorageValue<#typ> for #name<#traitinstance> {
|
||||
type Query = #gettype;
|
||||
|
||||
/// Get the storage key.
|
||||
fn key() -> &'static [u8] {
|
||||
#key_string.as_bytes()
|
||||
}
|
||||
|
||||
/// Load the value from the provided storage instance.
|
||||
fn get<S: #scrate::GenericStorage>(storage: &S) -> Self::Query {
|
||||
storage.get(<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::key())
|
||||
.#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Take a value from storage, removing it afterwards.
|
||||
fn take<S: #scrate::GenericStorage>(storage: &S) -> Self::Query {
|
||||
storage.take(<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::key())
|
||||
.#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Mutate the value under a key.
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::GenericStorage>(f: F, storage: &S) -> R {
|
||||
let mut val = <Self as #scrate::storage::generator::StorageValue<#typ>>::get(storage);
|
||||
|
||||
let ret = f(&mut val);
|
||||
#mutate_impl ;
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
let kty = stk.expect("is not simple; qed");
|
||||
let mutate_impl = if !is_option {
|
||||
quote!{
|
||||
<Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::insert(key, &val, storage)
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
match val {
|
||||
Some(ref val) => <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::insert(key, &val, storage),
|
||||
None => <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::remove(key, storage),
|
||||
}
|
||||
}
|
||||
};
|
||||
let prefix_string = cratename.to_string() + " " + &name.to_string();
|
||||
// generator for map
|
||||
quote!{
|
||||
#visibility struct #name<#traitinstance: #traittype>(#scrate::storage::generator::PhantomData<#traitinstance>);
|
||||
|
||||
impl<#traitinstance: #traittype> #scrate::storage::generator::StorageMap<#kty, #typ> for #name<#traitinstance> {
|
||||
type Query = #gettype;
|
||||
|
||||
/// Get the prefix key in storage.
|
||||
fn prefix() -> &'static [u8] {
|
||||
#prefix_string.as_bytes()
|
||||
}
|
||||
|
||||
/// Get the storage key used to fetch a value corresponding to a specific key.
|
||||
fn key_for(x: &#kty) -> #scrate::rstd::vec::Vec<u8> {
|
||||
let mut key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::prefix().to_vec();
|
||||
#scrate::codec::Encode::encode_to(x, &mut key);
|
||||
key
|
||||
}
|
||||
|
||||
/// Load the value associated with the given key from the map.
|
||||
fn get<S: #scrate::GenericStorage>(key: &#kty, storage: &S) -> Self::Query {
|
||||
let key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(key);
|
||||
storage.get(&key[..]).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Take the value, reading and removing it.
|
||||
fn take<S: #scrate::GenericStorage>(key: &#kty, storage: &S) -> Self::Query {
|
||||
let key = <#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>>::key_for(key);
|
||||
storage.take(&key[..]).#option_simple_1(|| #fielddefault)
|
||||
}
|
||||
|
||||
/// Mutate the value under a key
|
||||
fn mutate<R, F: FnOnce(&mut Self::Query) -> R, S: #scrate::GenericStorage>(key: &#kty, f: F, storage: &S) -> R {
|
||||
let mut val = <Self as #scrate::storage::generator::StorageMap<#kty, #typ>>::take(key, storage);
|
||||
|
||||
let ret = f(&mut val);
|
||||
#mutate_impl ;
|
||||
ret
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
impls.extend(implementation)
|
||||
}
|
||||
impls
|
||||
}
|
||||
|
||||
|
||||
fn decl_store_items(
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
) -> TokenStream2 {
|
||||
storage_lines.inner.iter().map(|sline| &sline.name)
|
||||
.fold(TokenStream2::new(), |mut items, name| {
|
||||
items.extend(quote!(type #name;));
|
||||
items
|
||||
})
|
||||
}
|
||||
|
||||
fn impl_store_items(
|
||||
traitinstance: &Ident,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
) -> TokenStream2 {
|
||||
storage_lines.inner.iter().map(|sline| &sline.name)
|
||||
.fold(TokenStream2::new(), |mut items, name| {
|
||||
items.extend(quote!(type #name = #name<#traitinstance>;));
|
||||
items
|
||||
})
|
||||
}
|
||||
|
||||
fn impl_store_fns(
|
||||
scrate: &TokenStream2,
|
||||
traitinstance: &Ident,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
) -> TokenStream2 {
|
||||
let mut items = TokenStream2::new();
|
||||
for sline in storage_lines.inner.iter() {
|
||||
let DeclStorageLine {
|
||||
name,
|
||||
getter,
|
||||
storage_type,
|
||||
..
|
||||
} = sline;
|
||||
|
||||
if let Some(getter) = getter {
|
||||
let get_fn = &getter.getfn.content;
|
||||
let (is_simple, extracted_opt, stk, gettype) = match storage_type {
|
||||
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
|
||||
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
|
||||
};
|
||||
|
||||
let typ = extracted_opt.unwrap_or(quote!(#gettype));
|
||||
let item = if is_simple {
|
||||
quote!{
|
||||
pub fn #get_fn() -> #gettype {
|
||||
<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>> :: get(&#scrate::storage::RuntimeStorage)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let kty = stk.expect("is not simple; qed");
|
||||
// map
|
||||
quote!{
|
||||
pub fn #get_fn<K: #scrate::storage::generator::Borrow<#kty>>(key: K) -> #gettype {
|
||||
<#name<#traitinstance> as #scrate::storage::generator::StorageMap<#kty, #typ>> :: get(key.borrow(), &#scrate::storage::RuntimeStorage)
|
||||
}
|
||||
}
|
||||
};
|
||||
items.extend(item);
|
||||
}
|
||||
}
|
||||
items
|
||||
}
|
||||
|
||||
fn store_functions_to_metadata (
|
||||
scrate: &TokenStream2,
|
||||
storage_lines: &ext::Punctuated<DeclStorageLine, Token![;]>,
|
||||
) -> TokenStream2 {
|
||||
|
||||
let mut items = TokenStream2::new();
|
||||
for sline in storage_lines.inner.iter() {
|
||||
let DeclStorageLine {
|
||||
attrs,
|
||||
name,
|
||||
storage_type,
|
||||
..
|
||||
} = sline;
|
||||
|
||||
let (is_simple, extracted_opt, stk, gettype) = match storage_type {
|
||||
DeclStorageType::Simple(ref st) => (true, ext::extract_type_option(st), None, st),
|
||||
DeclStorageType::Map(ref map) => (false, ext::extract_type_option(&map.value), Some(&map.key), &map.value),
|
||||
};
|
||||
|
||||
let is_option = extracted_opt.is_some();
|
||||
let typ = extracted_opt.unwrap_or(quote!( #gettype ));
|
||||
let stype = if is_simple {
|
||||
let styp = typ.to_string().replace(" ","");
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionType::Plain(
|
||||
#scrate::storage::generator::DecodeDifferent::Encode(#styp),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
let kty = stk.expect("is not simple; qed");
|
||||
let kty = quote!(#kty).to_string();
|
||||
let styp = typ.to_string().replace(" ","");
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionType::Map {
|
||||
key: #scrate::storage::generator::DecodeDifferent::Encode(#kty),
|
||||
value: #scrate::storage::generator::DecodeDifferent::Encode(#styp),
|
||||
}
|
||||
}
|
||||
};
|
||||
let modifier = if !is_option {
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionModifier::Default
|
||||
}
|
||||
} else {
|
||||
quote!{
|
||||
#scrate::storage::generator::StorageFunctionModifier::Optional
|
||||
}
|
||||
};
|
||||
let mut docs = TokenStream2::new();
|
||||
for attr in attrs.inner.iter().filter_map(|v| v.interpret_meta()) {
|
||||
if let syn::Meta::NameValue(syn::MetaNameValue{
|
||||
ref ident,
|
||||
ref lit,
|
||||
..
|
||||
}) = attr {
|
||||
if ident == "doc" {
|
||||
docs.extend(quote!(#lit,));
|
||||
}
|
||||
}
|
||||
}
|
||||
let str_name = name.to_string();
|
||||
let item = quote! {
|
||||
#scrate::storage::generator::StorageFunctionMetadata {
|
||||
name: #scrate::storage::generator::DecodeDifferent::Encode(#str_name),
|
||||
modifier: #modifier,
|
||||
ty: #stype,
|
||||
documentation: #scrate::storage::generator::DecodeDifferent::Encode(&[ #docs ]),
|
||||
},
|
||||
};
|
||||
items.extend(item);
|
||||
}
|
||||
|
||||
quote!{
|
||||
#scrate::storage::generator::DecodeDifferent::Encode(&[
|
||||
#items
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "srml-support-procedural-tools"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[dependencies]
|
||||
srml-support-procedural-tools-derive = { path = "./derive" }
|
||||
proc-macro2 = "0.4"
|
||||
quote = { version = "0.6" }
|
||||
syn = { version = "0.15", features = ["full"] }
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "srml-support-procedural-tools-derive"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "0.4.24"
|
||||
quote = { version = "0.6.10", features = ["proc-macro"] }
|
||||
syn = { version = "0.15.21", features = ["proc-macro" ,"full", "extra-traits", "parsing"] }
|
||||
@@ -0,0 +1,229 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
// tag::description[]
|
||||
//! Use to derive parsing for parsing struct.
|
||||
// end::description[]
|
||||
|
||||
|
||||
#![recursion_limit = "128"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate syn;
|
||||
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate proc_macro2;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
|
||||
|
||||
pub(crate) fn fields_idents(
|
||||
fields: impl Iterator<Item = syn::Field>,
|
||||
) -> impl Iterator<Item = proc_macro2::TokenStream> {
|
||||
fields.enumerate().map(|(ix, field)| {
|
||||
field.ident.clone().map(|i| quote!{#i}).unwrap_or_else(|| {
|
||||
let f_ix: syn::Ident = syn::Ident::new(&format!("f_{}", ix), Span::call_site());
|
||||
quote!( #f_ix )
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn fields_access(
|
||||
fields: impl Iterator<Item = syn::Field>,
|
||||
) -> impl Iterator<Item = proc_macro2::TokenStream> {
|
||||
fields.enumerate().map(|(ix, field)| {
|
||||
field.ident.clone().map(|i| quote!( #i )).unwrap_or_else(|| {
|
||||
let f_ix: syn::Index = syn::Index {
|
||||
index: ix as u32,
|
||||
span: Span::call_site(),
|
||||
};
|
||||
quote!( #f_ix )
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// self defined parsing struct (use where clause on struct for it: not meant for good struct
|
||||
/// design but fast parse impl).
|
||||
#[proc_macro_derive(ParseStruct)]
|
||||
pub fn derive_parse_struct(input: TokenStream) -> TokenStream {
|
||||
let syn::ItemStruct {
|
||||
ident,
|
||||
generics,
|
||||
fields,
|
||||
..
|
||||
} = parse_macro_input!(input as syn::ItemStruct);
|
||||
let field_names = {
|
||||
let name = fields_idents(fields.iter().map(Clone::clone));
|
||||
quote!{
|
||||
#(
|
||||
#name,
|
||||
)*
|
||||
}
|
||||
};
|
||||
let field = fields_idents(fields.iter().map(Clone::clone));
|
||||
let tokens = quote! {
|
||||
impl #generics syn::parse::Parse for #ident #generics {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
|
||||
#(
|
||||
let #field = input.parse()?;
|
||||
)*
|
||||
Ok(Self {
|
||||
#field_names
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
tokens.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(ToTokensStruct)]
|
||||
pub fn derive_totokens_struct(input: TokenStream) -> TokenStream {
|
||||
let syn::ItemStruct {
|
||||
ident,
|
||||
generics,
|
||||
fields,
|
||||
..
|
||||
} = parse_macro_input!(input as syn::ItemStruct);
|
||||
let fields = fields_access(fields.iter().map(Clone::clone));
|
||||
let tokens = quote! {
|
||||
|
||||
impl #generics quote::ToTokens for #ident #generics {
|
||||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||
#(
|
||||
self.#fields.to_tokens(tokens);
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
tokens.into()
|
||||
}
|
||||
|
||||
|
||||
/// self defined parsing enum, variant are tested in order of definition.
|
||||
/// Empty variant allways true.
|
||||
/// Please use carefully, this will fully parse successfull variant twice.
|
||||
#[proc_macro_derive(ParseEnum)]
|
||||
pub fn derive_parse_enum(input: TokenStream) -> TokenStream {
|
||||
|
||||
let syn::ItemEnum {
|
||||
ident,
|
||||
generics,
|
||||
variants,
|
||||
..
|
||||
} = parse_macro_input!(input as syn::ItemEnum);
|
||||
let variants = variants.iter().map(|v| {
|
||||
let variant_ident = v.ident.clone();
|
||||
let fields_build = if v.fields.iter().count() > 0 {
|
||||
let fields_id = fields_idents(v.fields.iter().map(Clone::clone));
|
||||
quote!( (#(#fields_id), *) )
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
|
||||
let fields_procs = fields_idents(v.fields.iter().map(Clone::clone))
|
||||
.map(|fident| {
|
||||
quote!{
|
||||
let mut #fident = match fork.parse() {
|
||||
Ok(r) => r,
|
||||
Err(_e) => break,
|
||||
};
|
||||
}
|
||||
});
|
||||
let fields_procs_again = fields_idents(v.fields.iter().map(Clone::clone))
|
||||
.map(|fident| {
|
||||
quote!{
|
||||
#fident = input.parse().expect("was parsed just before");
|
||||
}
|
||||
});
|
||||
|
||||
// double parse to update input cursor position
|
||||
// next syn crate version should be checked for a way
|
||||
// to copy position/state from a fork
|
||||
quote!{
|
||||
let mut fork = input.fork();
|
||||
loop {
|
||||
#(#fields_procs)*
|
||||
#(#fields_procs_again)*
|
||||
return Ok(#ident::#variant_ident#fields_build);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let tokens = quote! {
|
||||
impl #generics syn::parse::Parse for #ident #generics {
|
||||
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
|
||||
#(
|
||||
#variants
|
||||
)*
|
||||
// no early return from any variants
|
||||
Err(
|
||||
syn::parse::Error::new(
|
||||
proc_macro2::Span::call_site(),
|
||||
"derived enum no matching variants"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
tokens.into()
|
||||
}
|
||||
|
||||
/// only output field (empty field act as a None)
|
||||
#[proc_macro_derive(ToTokensEnum)]
|
||||
pub fn derive_totokens_enum(input: TokenStream) -> TokenStream {
|
||||
let syn::ItemEnum {
|
||||
ident,
|
||||
generics,
|
||||
variants,
|
||||
..
|
||||
} = parse_macro_input!(input as syn::ItemEnum);
|
||||
let variants = variants.iter().map(|v| {
|
||||
let v_ident = v.ident.clone();
|
||||
let fields_build = if v.fields.iter().count() > 0 {
|
||||
let fields_id = fields_idents(v.fields.iter().map(Clone::clone));
|
||||
quote!( (#(#fields_id), *) )
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let field = fields_idents(v.fields.iter().map(Clone::clone));
|
||||
quote! {
|
||||
#ident::#v_ident#fields_build => {
|
||||
#(
|
||||
#field.to_tokens(tokens);
|
||||
)*
|
||||
},
|
||||
}
|
||||
});
|
||||
let tokens = quote! {
|
||||
impl #generics quote::ToTokens for #ident #generics {
|
||||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||
match self {
|
||||
#(
|
||||
#variants
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tokens.into()
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
// tag::description[]
|
||||
//! Proc macro helpers for procedural macros
|
||||
// end::description[]
|
||||
|
||||
extern crate syn;
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
extern crate proc_macro2;
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
#[macro_use] extern crate srml_support_procedural_tools_derive;
|
||||
|
||||
// reexport proc macros
|
||||
pub use srml_support_procedural_tools_derive::*;
|
||||
|
||||
pub mod syn_ext;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! custom_keyword_impl {
|
||||
($name:ident, $keyident:expr, $keydisp:expr) => {
|
||||
|
||||
impl CustomKeyword for $name {
|
||||
fn ident() -> &'static str { $keyident }
|
||||
fn display() -> &'static str { $keydisp }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! custom_keyword {
|
||||
($name:ident, $keyident:expr, $keydisp:expr) => {
|
||||
|
||||
#[derive(Debug)]
|
||||
struct $name;
|
||||
|
||||
custom_keyword_impl!($name, $keyident, $keydisp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO following functions are copied from sr-api-macros : do a merge to get a unique procedural
|
||||
// macro tooling crate (this crate path does not look good for it)
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use syn::Ident;
|
||||
|
||||
fn generate_hidden_includes_mod_name(unique_id: &str) -> Ident {
|
||||
Ident::new(&format!("sr_api_hidden_includes_{}", unique_id), Span::call_site())
|
||||
}
|
||||
|
||||
/// Generates the access to the `subtrate_client` crate.
|
||||
pub fn generate_crate_access(unique_id: &str, def_crate: &str) -> TokenStream {
|
||||
if ::std::env::var("CARGO_PKG_NAME").unwrap() == def_crate {
|
||||
quote!( crate )
|
||||
} else {
|
||||
let mod_name = generate_hidden_includes_mod_name(unique_id);
|
||||
quote!( self::#mod_name::hidden_include )
|
||||
}.into()
|
||||
}
|
||||
|
||||
/// Generates the hidden includes that are required to make the macro independent from its scope.
|
||||
pub fn generate_hidden_includes(unique_id: &str, def_crate: &str, crate_id: &str) -> TokenStream {
|
||||
let crate_id = Ident::new(crate_id, Span::call_site());
|
||||
if ::std::env::var("CARGO_PKG_NAME").unwrap() == def_crate {
|
||||
TokenStream::new()
|
||||
} else {
|
||||
let mod_name = generate_hidden_includes_mod_name(unique_id);
|
||||
quote!(
|
||||
#[doc(hidden)]
|
||||
mod #mod_name {
|
||||
pub extern crate #crate_id as hidden_include;
|
||||
}
|
||||
)
|
||||
}.into()
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
// Copyright 2017-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/>.
|
||||
|
||||
// tag::description[]
|
||||
//! Extension to syn types, mainly for parsing
|
||||
// end::description[]
|
||||
|
||||
use syn::parse::{
|
||||
Parse,
|
||||
ParseStream,
|
||||
Result,
|
||||
};
|
||||
use syn::token::CustomKeyword;
|
||||
use proc_macro2::TokenStream as T2;
|
||||
use quote::ToTokens;
|
||||
use std::iter::once;
|
||||
use syn::Ident;
|
||||
|
||||
/// stop parsing here getting remaining token as content
|
||||
/// Warn duplicate stream (part of)
|
||||
#[derive(ParseStruct, ToTokensStruct, Debug)]
|
||||
pub struct StopParse {
|
||||
pub inner: T2,
|
||||
}
|
||||
|
||||
// inner macro really dependant on syn naming convention, do not export
|
||||
macro_rules! groups_impl {
|
||||
($name:ident, $tok:ident, $deli:ident, $parse:ident) => {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct $name<P> {
|
||||
pub token: syn::token::$tok,
|
||||
pub content: P,
|
||||
}
|
||||
|
||||
impl<P: Parse> Parse for $name<P> {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let syn::group::$name { token, content } = syn::group::$parse(input)?;
|
||||
let content = content.parse()?;
|
||||
Ok($name { token, content, })
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: ToTokens> ToTokens for $name<P> {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
let mut inner_stream = T2::new();
|
||||
self.content.to_tokens(&mut inner_stream);
|
||||
let token_tree: proc_macro2::TokenTree =
|
||||
proc_macro2::Group::new(proc_macro2::Delimiter::$deli, inner_stream).into();
|
||||
tokens.extend(once(token_tree));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
groups_impl!(Braces, Brace, Brace, parse_braces);
|
||||
groups_impl!(Brackets, Bracket, Bracket, parse_brackets);
|
||||
groups_impl!(Parens, Paren, Parenthesis, parse_parens);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CustomToken<T>(std::marker::PhantomData<T>);
|
||||
|
||||
impl<T: CustomKeyword> Parse for CustomToken<T> {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let ident: syn::Ident = input.parse()?;
|
||||
|
||||
if ident.to_string().as_str() != T::ident() {
|
||||
return Err(syn::parse::Error::new_spanned(ident, "expected another custom token"))
|
||||
}
|
||||
Ok(CustomToken(std::marker::PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: CustomKeyword> ToTokens for CustomToken<T> {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
use std::str::FromStr;
|
||||
tokens.extend(T2::from_str(T::ident()).expect("custom keyword should parse to ident"));
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: CustomKeyword> CustomKeyword for CustomToken<T> {
|
||||
fn ident() -> &'static str { <T as CustomKeyword>::ident() }
|
||||
fn display() -> &'static str { <T as CustomKeyword>::display() }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PunctuatedInner<P,T,V> {
|
||||
pub inner: syn::punctuated::Punctuated<P,T>,
|
||||
pub variant: V,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NoTrailing;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Trailing;
|
||||
|
||||
pub type Punctuated<P,T> = PunctuatedInner<P,T,NoTrailing>;
|
||||
|
||||
pub type PunctuatedTrailing<P,T> = PunctuatedInner<P,T,Trailing>;
|
||||
|
||||
impl<P: Parse, T: Parse + syn::token::Token> Parse for PunctuatedInner<P,T,Trailing> {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
Ok(PunctuatedInner {
|
||||
inner: syn::punctuated::Punctuated::parse_separated_nonempty(input)?,
|
||||
variant: Trailing,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: Parse, T: Parse> Parse for PunctuatedInner<P,T,NoTrailing> {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
Ok(PunctuatedInner {
|
||||
inner: syn::punctuated::Punctuated::parse_terminated(input)?,
|
||||
variant: NoTrailing,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: ToTokens, T: ToTokens, V> ToTokens for PunctuatedInner<P,T,V> {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
self.inner.to_tokens(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
/// Note that syn Meta is almost fine for use case (lacks only `ToToken`)
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Meta {
|
||||
pub inner: syn::Meta,
|
||||
}
|
||||
|
||||
impl Parse for Meta {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
Ok(Meta {
|
||||
inner: syn::Meta::parse(input)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for Meta {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
match self.inner {
|
||||
syn::Meta::Word(ref ident) => {
|
||||
let ident = ident.clone();
|
||||
let toks = quote!{
|
||||
#[#ident]
|
||||
};
|
||||
tokens.extend(toks);
|
||||
},
|
||||
syn::Meta::List(ref l) => l.to_tokens(tokens),
|
||||
syn::Meta::NameValue(ref n) => n.to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OuterAttributes {
|
||||
pub inner: Vec<syn::Attribute>,
|
||||
}
|
||||
|
||||
impl Parse for OuterAttributes {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let inner = syn::Attribute::parse_outer(input)?;
|
||||
Ok(OuterAttributes {
|
||||
inner,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for OuterAttributes {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
for att in self.inner.iter() {
|
||||
att.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Seq<P> {
|
||||
pub inner: Vec<P>,
|
||||
}
|
||||
|
||||
impl<P: Parse> Parse for Seq<P> {
|
||||
// Note that it cost a double parsing (same as enum derive)
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let mut inner = Vec::new();
|
||||
loop {
|
||||
let fork = input.fork();
|
||||
let res: Result<P> = fork.parse();
|
||||
match res {
|
||||
Ok(_item) => {
|
||||
// move cursor
|
||||
let item: P = input.parse().expect("Same parsing ran before");
|
||||
inner.push(item);
|
||||
},
|
||||
Err(_e) => break,
|
||||
}
|
||||
}
|
||||
Ok(Seq { inner })
|
||||
}
|
||||
}
|
||||
|
||||
impl<P: ToTokens> ToTokens for Seq<P> {
|
||||
fn to_tokens(&self, tokens: &mut T2) {
|
||||
for p in self.inner.iter() {
|
||||
p.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_type_option(typ: &syn::Type) -> Option<T2> {
|
||||
if let syn::Type::Path(ref path) = typ {
|
||||
path.path.segments.last().and_then(|v| {
|
||||
if v.value().ident == "Option" {
|
||||
if let syn::PathArguments::AngleBracketed(ref a) = v.value().arguments {
|
||||
let args = &a.args;
|
||||
Some(quote!{ #args })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_parametric_type_def(typ: &syn::Type, default: bool) -> bool {
|
||||
match *typ {
|
||||
syn::Type::Path(ref path) => {
|
||||
path.path.segments.iter().any(|v| {
|
||||
if let syn::PathArguments::AngleBracketed(..) = v.arguments {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
},
|
||||
syn::Type::Slice(ref inner) => is_parametric_type_def(&inner.elem, default),
|
||||
syn::Type::Array(ref inner) => is_parametric_type_def(&inner.elem, default),
|
||||
syn::Type::Ptr(ref inner) => is_parametric_type_def(&inner.elem, default),
|
||||
syn::Type::Reference(ref inner) => is_parametric_type_def(&inner.elem, default),
|
||||
syn::Type::BareFn(ref inner) => inner.variadic.is_some(),
|
||||
syn::Type::Never(..) => false,
|
||||
syn::Type::Tuple(ref inner) =>
|
||||
inner.elems.iter().any(|t| is_parametric_type_def(t, default)),
|
||||
syn::Type::TraitObject(..) => true,
|
||||
syn::Type::ImplTrait(..) => true,
|
||||
syn::Type::Paren(ref inner) => is_parametric_type_def(&inner.elem, default),
|
||||
syn::Type::Group(ref inner) => is_parametric_type_def(&inner.elem, default),
|
||||
syn::Type::Infer(..) => true,
|
||||
syn::Type::Macro(..) => default,
|
||||
syn::Type::Verbatim(..) => default,
|
||||
}
|
||||
}
|
||||
|
||||
/// check if type has any type parameter, defaults to true for some cases.
|
||||
pub fn is_parametric_type(typ: &syn::Type) -> bool {
|
||||
is_parametric_type_def(typ, true)
|
||||
}
|
||||
|
||||
fn has_parametric_type_def_in_path(path: &syn::Path, ident: &Ident, default: bool) -> bool {
|
||||
path.segments.iter().any(|v| {
|
||||
if ident == &v.ident {
|
||||
return true;
|
||||
}
|
||||
if let syn::PathArguments::AngleBracketed(ref a) = v.arguments {
|
||||
for arg in a.args.iter() {
|
||||
if let syn::GenericArgument::Type(ref typ) = arg {
|
||||
if has_parametric_type_def(typ, ident, default) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// potentially missing matches here
|
||||
}
|
||||
false
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
pub fn has_parametric_type_def(typ: &syn::Type, ident: &Ident, default: bool) -> bool {
|
||||
match *typ {
|
||||
syn::Type::Path(ref path) => has_parametric_type_def_in_path(&path.path, ident, default),
|
||||
syn::Type::Slice(ref inner) => has_parametric_type_def(&inner.elem, ident, default),
|
||||
syn::Type::Array(ref inner) => has_parametric_type_def(&inner.elem, ident, default),
|
||||
syn::Type::Ptr(ref inner) => has_parametric_type_def(&inner.elem, ident, default),
|
||||
syn::Type::Reference(ref inner) => has_parametric_type_def(&inner.elem, ident, default),
|
||||
syn::Type::BareFn(ref inner) => inner.variadic.is_some(),
|
||||
syn::Type::Never(..) => false,
|
||||
syn::Type::Tuple(ref inner) =>
|
||||
inner.elems.iter().any(|t| has_parametric_type_def(t, ident, default)),
|
||||
syn::Type::TraitObject(ref to) => {
|
||||
to.bounds.iter().any(|bound| {
|
||||
if let syn::TypeParamBound::Trait(ref t) = bound {
|
||||
has_parametric_type_def_in_path(&t.path, ident, default)
|
||||
} else { false }
|
||||
})
|
||||
},
|
||||
syn::Type::ImplTrait(ref it) => {
|
||||
it.bounds.iter().any(|bound| {
|
||||
if let syn::TypeParamBound::Trait(ref t) = bound {
|
||||
has_parametric_type_def_in_path(&t.path, ident, default)
|
||||
} else { false }
|
||||
})
|
||||
},
|
||||
syn::Type::Paren(ref inner) => has_parametric_type_def(&inner.elem, ident, default),
|
||||
syn::Type::Group(ref inner) => has_parametric_type_def(&inner.elem, ident, default),
|
||||
syn::Type::Infer(..) => default,
|
||||
syn::Type::Macro(..) => default,
|
||||
syn::Type::Verbatim(..) => default,
|
||||
}
|
||||
}
|
||||
|
||||
/// check if type has a type parameter, defaults to true for some cases.
|
||||
pub fn has_parametric_type(typ: &syn::Type, ident: &Ident) -> bool {
|
||||
has_parametric_type_def(typ, ident, true)
|
||||
}
|
||||
@@ -31,6 +31,9 @@ extern crate srml_metadata;
|
||||
|
||||
extern crate mashup;
|
||||
|
||||
#[macro_use]
|
||||
extern crate srml_support_procedural;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate pretty_assertions;
|
||||
@@ -67,6 +70,9 @@ pub use self::dispatch::{Parameter, Dispatchable, Callable, IsSubType};
|
||||
pub use self::metadata::RuntimeMetadata;
|
||||
pub use runtime_io::print;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use srml_support_procedural::decl_storage;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fail {
|
||||
( $y:expr ) => {{
|
||||
|
||||
@@ -188,7 +188,6 @@ mod tests {
|
||||
StorageMethod : Option<u32>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(_marker) : ::std::marker::PhantomData<T>;
|
||||
build(|_, _, _| {});
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -207,7 +207,6 @@ mod tests {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
period: 5,
|
||||
_genesis_phantom_data: Default::default()
|
||||
}.build_storage().unwrap().0);
|
||||
|
||||
with_externalities(&mut TestExternalities::new(t), || {
|
||||
@@ -223,7 +222,6 @@ mod tests {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
period: 5,
|
||||
_genesis_phantom_data: Default::default()
|
||||
}.build_storage().unwrap().0);
|
||||
|
||||
with_externalities(&mut TestExternalities::new(t), || {
|
||||
@@ -239,7 +237,6 @@ mod tests {
|
||||
let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
|
||||
t.extend(GenesisConfig::<Test> {
|
||||
period: 5,
|
||||
_genesis_phantom_data: Default::default()
|
||||
}.build_storage().unwrap().0);
|
||||
|
||||
with_externalities(&mut TestExternalities::new(t), || {
|
||||
|
||||
@@ -330,14 +330,12 @@ mod tests {
|
||||
creation_fee: 0,
|
||||
existential_deposit: 0,
|
||||
reclaim_rebate: 0,
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.extend(GenesisConfig::<Test>{
|
||||
proposal_bond: Permill::from_percent(5),
|
||||
proposal_bond_minimum: 1,
|
||||
spend_period: 2,
|
||||
burn: Permill::from_percent(50),
|
||||
_genesis_phantom_data: Default::default(),
|
||||
}.build_storage().unwrap().0);
|
||||
t.into()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ sr-std = { path = "../../core/sr-std", default-features = false }
|
||||
sr-io = { path = "../../core/sr-io", default-features = false }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
srml-support = { path = "../support", default-features = false }
|
||||
srml-support-procedural = { path = "../support/procedural" }
|
||||
srml-system = { path = "../system", default-features = false }
|
||||
srml-consensus = { path = "../consensus", default-features = false }
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ extern crate parity_codec_derive;
|
||||
extern crate parity_codec as codec;
|
||||
#[macro_use]
|
||||
extern crate srml_support as support;
|
||||
|
||||
extern crate srml_system as system;
|
||||
extern crate srml_consensus as consensus;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user