From a9bc0adf17b39482a163234fc2de4fbd7dd8707f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 29 Jun 2020 13:26:19 +0100 Subject: [PATCH 01/39] WIP --- abi/Cargo.toml | 1 + abi/src/lib.rs | 54 ++++++++++++++++++++++++++++++++++- lang/macro/src/codegen/abi.rs | 4 +-- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/abi/Cargo.toml b/abi/Cargo.toml index f6fedec3521..89c3bf0e025 100644 --- a/abi/Cargo.toml +++ b/abi/Cargo.toml @@ -21,6 +21,7 @@ ink_primitives = { version = "2.1.0", path = "../primitives/", default-features serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } derive_more = { version = "0.99", default-features = false, features = ["from"] } scale-info = { version = "0.2", default-features = false, features = ["derive"] } +semver = { version = "0.10.0", features = ["serde"] } [dev-dependencies] serde_json = "1.0" diff --git a/abi/src/lib.rs b/abi/src/lib.rs index d0b1e409688..b3e6de16567 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -41,6 +41,7 @@ pub use self::specs::{ ReturnTypeSpec, TypeSpec, }; +use core::marker::PhantomData; #[cfg(feature = "derive")] use scale_info::{ form::CompactForm, @@ -52,6 +53,7 @@ use serde::Serialize; /// An entire ink! project for ABI file generation purposes. #[derive(Debug, Serialize)] pub struct InkProject { + metadata: InkProjectMetadata, registry: Registry, #[serde(rename = "storage")] layout: layout2::Layout, @@ -61,16 +63,66 @@ pub struct InkProject { impl InkProject { /// Creates a new ink! project. - pub fn new(layout: L, spec: S) -> Self + pub fn new(metadata: M, layout: L, spec: S) -> Self where + M: Into, L: Into, S: Into, { let mut registry = Registry::new(); Self { + metadata: metadata.into(), layout: layout.into().into_compact(&mut registry), spec: spec.into().into_compact(&mut registry), registry, } } } + +#[derive(Debug, Serialize)] +pub struct InkProjectMetadata { + version: semver::Version +} + +impl From> for InkProjectMetadata { + fn from(builder: InkProjectMetadataBuilder) -> Self { + builder.done() + } +} + +/// Type state for builders to tell that some mandatory state has not yet been set +/// yet or to fail upon setting the same state multiple times. +pub struct Missing(PhantomData S>); + +mod state { + //! Type states that tell what state of the project metadata has not + //! yet been set properly for a valid construction. + + /// Type state for the version of the project metadata. + pub struct Version; +} + +pub struct InkProjectMetadataBuilder { + metadata: InkProjectMetadata, + marker: PhantomData (Version)> +} + +impl InkProjectMetadataBuilder> { + // todo: error type? + pub fn version(self, version: S) -> Result, ()> { + let version = semver::Version::parse(version.as_ref()).map_err(|_| ())?; + Ok(InkProjectMetadataBuilder { + metadata: InkProjectMetadata { + version, + ..self.metadata + }, + marker: PhantomData, + }) + } +} + +impl InkProjectMetadataBuilder { + fn done(self) -> InkProjectMetadata { + self.metadata + } +} diff --git a/lang/macro/src/codegen/abi.rs b/lang/macro/src/codegen/abi.rs index 231474e9c4e..3b5eac761a6 100644 --- a/lang/macro/src/codegen/abi.rs +++ b/lang/macro/src/codegen/abi.rs @@ -42,14 +42,14 @@ impl GenerateCode for GenerateAbi<'_> { #[cfg(not(feature = "ink-as-dependency"))] const _: () = { #[no_mangle] - pub fn __ink_generate_metadata() -> ::ink_abi::InkProject { + pub fn __ink_generate_metadata(metadata: ::ink_abi::InkProjectMetadata) -> ::ink_abi::InkProject { let contract: ::ink_abi::ContractSpec = { #contract }; let layout: ::ink_abi::layout2::Layout = { #layout }; - ::ink_abi::InkProject::new(layout, contract) + ::ink_abi::InkProject::new(metadata, layout, contract) } }; } From 1906faf1dd4a2d68267dac873987d4f15ad32051 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 30 Jun 2020 07:14:46 +0100 Subject: [PATCH 02/39] WIP --- abi/src/lib.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/abi/src/lib.rs b/abi/src/lib.rs index b3e6de16567..334e55131ee 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -53,12 +53,11 @@ use serde::Serialize; /// An entire ink! project for ABI file generation purposes. #[derive(Debug, Serialize)] pub struct InkProject { - metadata: InkProjectMetadata, - registry: Registry, - #[serde(rename = "storage")] - layout: layout2::Layout, - #[serde(rename = "contract")] - spec: ContractSpec, + metadata_version: semver::Version, + source: InkProjectSource, + contract: InkProjectContract, + user: InkProjectUser, + spec: InkProjectSpec, } impl InkProject { @@ -80,8 +79,17 @@ impl InkProject { } #[derive(Debug, Serialize)] -pub struct InkProjectMetadata { - version: semver::Version +pub struct InkProjectSource { + hash: &'static str, + language: &'static str, + compiler: &'static str, +} + +#[derive(Debug, Serialize)] +pub struct InkProjecContract { + name: &'static str, + version: semver::Version, + authors: Vec<&'static str>, } impl From> for InkProjectMetadata { @@ -90,6 +98,14 @@ impl From> for InkProjectMetadata { } } +struct InkProjectSpec { + #[serde(flatten)] // should result in a only a "types" field + registry: Registry, + #[serde(rename = "storage")] + layout: layout2::Layout, + spec: ContractSpec, +} + /// Type state for builders to tell that some mandatory state has not yet been set /// yet or to fail upon setting the same state multiple times. pub struct Missing(PhantomData S>); From b346f31edbe14afba61089b5e5549321b4764e8f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 30 Jun 2020 11:09:26 +0100 Subject: [PATCH 03/39] Iterating on InkProject types --- abi/Cargo.toml | 1 + abi/src/lib.rs | 72 +++++++++++++++++++++++++---------- lang/macro/src/codegen/abi.rs | 5 ++- 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/abi/Cargo.toml b/abi/Cargo.toml index 89c3bf0e025..637d0c4774e 100644 --- a/abi/Cargo.toml +++ b/abi/Cargo.toml @@ -22,6 +22,7 @@ serde = { version = "1.0", default-features = false, features = ["derive", "allo derive_more = { version = "0.99", default-features = false, features = ["from"] } scale-info = { version = "0.2", default-features = false, features = ["derive"] } semver = { version = "0.10.0", features = ["serde"] } +url = { version = "2.1.1", features = ["serde"] } [dev-dependencies] serde_json = "1.0" diff --git a/abi/src/lib.rs b/abi/src/lib.rs index 334e55131ee..73c8bdba9f5 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -48,36 +48,40 @@ use scale_info::{ IntoCompact as _, Registry, }; +use semver::Version; use serde::Serialize; +use url::Url; + +const METADATA_VERSION: &str = "0.1.0"; /// An entire ink! project for ABI file generation purposes. #[derive(Debug, Serialize)] pub struct InkProject { - metadata_version: semver::Version, - source: InkProjectSource, - contract: InkProjectContract, - user: InkProjectUser, + metadata_version: Version, + #[serde(flatten)] + extension: InkProjectExtension, spec: InkProjectSpec, } impl InkProject { - /// Creates a new ink! project. - pub fn new(metadata: M, layout: L, spec: S) -> Self - where - M: Into, - L: Into, - S: Into, - { - let mut registry = Registry::new(); - Self { - metadata: metadata.into(), - layout: layout.into().into_compact(&mut registry), - spec: spec.into().into_compact(&mut registry), - registry, + pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { + let metadata_version= Version::parse(METADATA_VERSION).expect("METADATA_VERSION is a valid semver string"); + InkProject { + metadata_version, + extension, + spec } } } +/// Additional metadata supplied externally, e.g. by a tool such as `cargo-contract` +#[derive(Debug, Serialize)] +pub struct InkProjectExtension { + source: InkProjectSource, + contract: InkProjectContract, + user: InkProjectUser, +} + #[derive(Debug, Serialize)] pub struct InkProjectSource { hash: &'static str, @@ -86,10 +90,21 @@ pub struct InkProjectSource { } #[derive(Debug, Serialize)] -pub struct InkProjecContract { +pub struct InkProjectContract { name: &'static str, - version: semver::Version, + version: Version, authors: Vec<&'static str>, + description: &'static str, + documentation: Url, + repository: Url, + homepage: Url, + license: &'static str, +} + +#[derive(Debug, Serialize)] +pub struct InkProjectUser { + #[serde(flatten)] + json: serde_json::Map } impl From> for InkProjectMetadata { @@ -98,6 +113,7 @@ impl From> for InkProjectMetadata { } } +#[derive(Debug, Serialize)] struct InkProjectSpec { #[serde(flatten)] // should result in a only a "types" field registry: Registry, @@ -106,6 +122,22 @@ struct InkProjectSpec { spec: ContractSpec, } +impl InkProjectSpec { + /// Creates a new ink! project. + pub fn new(layout: L, spec: S) -> Self + where + L: Into, + S: Into, + { + let mut registry = Registry::new(); + Self { + layout: layout.into().into_compact(&mut registry), + spec: spec.into().into_compact(&mut registry), + registry, + } + } +} + /// Type state for builders to tell that some mandatory state has not yet been set /// yet or to fail upon setting the same state multiple times. pub struct Missing(PhantomData S>); @@ -126,7 +158,7 @@ pub struct InkProjectMetadataBuilder { impl InkProjectMetadataBuilder> { // todo: error type? pub fn version(self, version: S) -> Result, ()> { - let version = semver::Version::parse(version.as_ref()).map_err(|_| ())?; + let version = Version::parse(version.as_ref()).map_err(|_| ())?; Ok(InkProjectMetadataBuilder { metadata: InkProjectMetadata { version, diff --git a/lang/macro/src/codegen/abi.rs b/lang/macro/src/codegen/abi.rs index 3b5eac761a6..6911235d5dc 100644 --- a/lang/macro/src/codegen/abi.rs +++ b/lang/macro/src/codegen/abi.rs @@ -42,14 +42,15 @@ impl GenerateCode for GenerateAbi<'_> { #[cfg(not(feature = "ink-as-dependency"))] const _: () = { #[no_mangle] - pub fn __ink_generate_metadata(metadata: ::ink_abi::InkProjectMetadata) -> ::ink_abi::InkProject { + pub fn __ink_generate_metadata(extension: ::ink_abi::InkProjectExtension) -> ::ink_abi::InkProject { let contract: ::ink_abi::ContractSpec = { #contract }; let layout: ::ink_abi::layout2::Layout = { #layout }; - ::ink_abi::InkProject::new(metadata, layout, contract) + let spec = ::ink_abi::InkSpec::new(layout, spec) + ::ink_abi::InkProject::new(extension, spec) } }; } From ea0b84b9ab9230be28305e6665e1d8dd711bfe83 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 1 Jul 2020 08:34:34 +0100 Subject: [PATCH 04/39] Extract InkProject to its own file --- metadata/src/lib.rs | 140 +++---------------------------------- metadata/src/project.rs | 150 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 131 deletions(-) create mode 100644 metadata/src/project.rs diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 73c8bdba9f5..2ae1a9b2ee5 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -21,9 +21,18 @@ extern crate alloc; mod tests; pub mod layout2; +mod project; mod specs; mod utils; +pub use self::project::{ + InkProject, + InkProjectExtension, + InkProjectSource, + InkProjectContract, + InkProjectUser, + InkProjectSpec, +}; pub use self::specs::{ ConstructorSpec, ConstructorSpecBuilder, @@ -41,136 +50,5 @@ pub use self::specs::{ ReturnTypeSpec, TypeSpec, }; -use core::marker::PhantomData; -#[cfg(feature = "derive")] -use scale_info::{ - form::CompactForm, - IntoCompact as _, - Registry, -}; -use semver::Version; -use serde::Serialize; -use url::Url; const METADATA_VERSION: &str = "0.1.0"; - -/// An entire ink! project for ABI file generation purposes. -#[derive(Debug, Serialize)] -pub struct InkProject { - metadata_version: Version, - #[serde(flatten)] - extension: InkProjectExtension, - spec: InkProjectSpec, -} - -impl InkProject { - pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { - let metadata_version= Version::parse(METADATA_VERSION).expect("METADATA_VERSION is a valid semver string"); - InkProject { - metadata_version, - extension, - spec - } - } -} - -/// Additional metadata supplied externally, e.g. by a tool such as `cargo-contract` -#[derive(Debug, Serialize)] -pub struct InkProjectExtension { - source: InkProjectSource, - contract: InkProjectContract, - user: InkProjectUser, -} - -#[derive(Debug, Serialize)] -pub struct InkProjectSource { - hash: &'static str, - language: &'static str, - compiler: &'static str, -} - -#[derive(Debug, Serialize)] -pub struct InkProjectContract { - name: &'static str, - version: Version, - authors: Vec<&'static str>, - description: &'static str, - documentation: Url, - repository: Url, - homepage: Url, - license: &'static str, -} - -#[derive(Debug, Serialize)] -pub struct InkProjectUser { - #[serde(flatten)] - json: serde_json::Map -} - -impl From> for InkProjectMetadata { - fn from(builder: InkProjectMetadataBuilder) -> Self { - builder.done() - } -} - -#[derive(Debug, Serialize)] -struct InkProjectSpec { - #[serde(flatten)] // should result in a only a "types" field - registry: Registry, - #[serde(rename = "storage")] - layout: layout2::Layout, - spec: ContractSpec, -} - -impl InkProjectSpec { - /// Creates a new ink! project. - pub fn new(layout: L, spec: S) -> Self - where - L: Into, - S: Into, - { - let mut registry = Registry::new(); - Self { - layout: layout.into().into_compact(&mut registry), - spec: spec.into().into_compact(&mut registry), - registry, - } - } -} - -/// Type state for builders to tell that some mandatory state has not yet been set -/// yet or to fail upon setting the same state multiple times. -pub struct Missing(PhantomData S>); - -mod state { - //! Type states that tell what state of the project metadata has not - //! yet been set properly for a valid construction. - - /// Type state for the version of the project metadata. - pub struct Version; -} - -pub struct InkProjectMetadataBuilder { - metadata: InkProjectMetadata, - marker: PhantomData (Version)> -} - -impl InkProjectMetadataBuilder> { - // todo: error type? - pub fn version(self, version: S) -> Result, ()> { - let version = Version::parse(version.as_ref()).map_err(|_| ())?; - Ok(InkProjectMetadataBuilder { - metadata: InkProjectMetadata { - version, - ..self.metadata - }, - marker: PhantomData, - }) - } -} - -impl InkProjectMetadataBuilder { - fn done(self) -> InkProjectMetadata { - self.metadata - } -} diff --git a/metadata/src/project.rs b/metadata/src/project.rs new file mode 100644 index 00000000000..8c13928e7d3 --- /dev/null +++ b/metadata/src/project.rs @@ -0,0 +1,150 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::marker::PhantomData; +#[cfg(feature = "derive")] +use scale_info::{ + form::CompactForm, + IntoCompact as _, + Registry, +}; +use semver::Version; +use serde::Serialize; +use url::Url; +use super::{ + ContractSpec, + layout2, + METADATA_VERSION +}; + +/// An entire ink! project for ABI file generation purposes. +#[derive(Debug, Serialize)] +pub struct InkProject { + metadata_version: Version, + #[serde(flatten)] + extension: InkProjectExtension, + spec: InkProjectSpec, +} + +impl InkProject { + pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { + let metadata_version= Version::parse(METADATA_VERSION).expect("METADATA_VERSION is a valid semver string"); + InkProject { + metadata_version, + extension, + spec + } + } +} + +/// Additional metadata supplied externally, e.g. by a tool such as `cargo-contract` +#[derive(Debug, Serialize)] +pub struct InkProjectExtension { + source: InkProjectSource, + contract: InkProjectContract, + user: InkProjectUser, +} + +#[derive(Debug, Serialize)] +pub struct InkProjectSource { + hash: &'static str, + language: &'static str, + compiler: &'static str, +} + +#[derive(Debug, Serialize)] +pub struct InkProjectContract { + name: &'static str, + version: Version, + authors: Vec<&'static str>, + description: &'static str, + documentation: Url, + repository: Url, + homepage: Url, + license: &'static str, +} + +#[derive(Debug, Serialize)] +pub struct InkProjectUser { + #[serde(flatten)] + json: serde_json::Map +} + +impl From> for InkProjectMetadata { + fn from(builder: InkProjectMetadataBuilder) -> Self { + builder.done() + } +} + +#[derive(Debug, Serialize)] +pub struct InkProjectSpec { + #[serde(flatten)] // should result in a only a "types" field + registry: Registry, + #[serde(rename = "storage")] + layout: layout2::Layout, + spec: ContractSpec, +} + +impl InkProjectSpec { + /// Creates a new ink! project. + pub fn new(layout: L, spec: S) -> Self + where + L: Into, + S: Into, + { + let mut registry = Registry::new(); + Self { + layout: layout.into().into_compact(&mut registry), + spec: spec.into().into_compact(&mut registry), + registry, + } + } +} + +/// Type state for builders to tell that some mandatory state has not yet been set +/// yet or to fail upon setting the same state multiple times. +pub struct Missing(PhantomData S>); + +mod state { + //! Type states that tell what state of the project metadata has not + //! yet been set properly for a valid construction. + + /// Type state for the version of the project metadata. + pub struct Version; +} + +pub struct InkProjectMetadataBuilder { + metadata: InkProjectMetadata, + marker: PhantomData (Version)> +} + +impl InkProjectMetadataBuilder> { + // todo: error type? + pub fn version(self, version: S) -> Result, ()> { + let version = Version::parse(version.as_ref()).map_err(|_| ())?; + Ok(InkProjectMetadataBuilder { + metadata: InkProjectMetadata { + version, + ..self.metadata + }, + marker: PhantomData, + }) + } +} + +impl InkProjectMetadataBuilder { + fn done(self) -> InkProjectMetadata { + self.metadata + } +} From f315b8a10cc6d52e3ad501edf762ec3efabe41b3 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 1 Jul 2020 11:25:12 +0100 Subject: [PATCH 05/39] More iteration on contract metadata --- metadata/Cargo.toml | 2 +- metadata/src/extension.rs | 230 ++++++++++++++++++++++++++++++++++++++ metadata/src/lib.rs | 60 +++++++++- metadata/src/project.rs | 150 ------------------------- 4 files changed, 287 insertions(+), 155 deletions(-) create mode 100644 metadata/src/extension.rs delete mode 100644 metadata/src/project.rs diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index 9bc7234cf68..0e7fb2439de 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -19,13 +19,13 @@ ink_prelude = { version = "2.1.0", path = "../prelude/", default-features = fals ink_primitives = { version = "2.1.0", path = "../primitives/", default-features = false } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } +serde_json = "1.0" derive_more = { version = "0.99", default-features = false, features = ["from"] } scale-info = { version = "0.2", default-features = false, features = ["derive"] } semver = { version = "0.10.0", features = ["serde"] } url = { version = "2.1.1", features = ["serde"] } [dev-dependencies] -serde_json = "1.0" assert-json-diff = "1.0.1" [features] diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs new file mode 100644 index 00000000000..7d6bde3be7c --- /dev/null +++ b/metadata/src/extension.rs @@ -0,0 +1,230 @@ +// Copyright 2018-2019 Parity Technologies (UK) Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::marker::PhantomData; +use semver::Version; +use serde::Serialize; +use serde_json::{Map, Value}; +use url::Url; + +/// Additional metadata supplied externally, e.g. by `cargo-contract`. +#[derive(Debug, Serialize)] +pub struct InkProjectExtension { + source: InkProjectSource, + contract: InkProjectContract, + #[serde(skip_serializing_if = "Option::is_none")] + user: Option, +} + +impl InkProjectExtension { + /// Constructs a new InkProjectExtension. + pub fn new(source: InkProjectSource, contract: InkProjectContract, user: Option) -> Self { + InkProjectExtension { source, contract, user } + } +} + +#[derive(Debug, Serialize)] +pub struct InkProjectSource { + hash: [u8; 32], + language: SourceLanguage, + compiler: SourceCompiler, +} + +impl InkProjectSource { + /// Constructs a new InkProjectSource. + pub fn new(hash: [u8; 32], language: SourceLanguage, compiler: SourceCompiler) -> Self { + InkProjectSource { hash, language, compiler } + } +} + +/// The language and version in which a smart contract is written. +// todo: custom serialize e.g. `ink! v0.3.0` +#[derive(Debug, Serialize)] +pub struct SourceLanguage { + language: Language, + version: Version, +} + +impl SourceLanguage { + /// Constructs a new SourceLanguage. + pub fn new(language: Language, version: Version) -> Self { + SourceLanguage { language, version } + } +} + +/// The language in which the smart contract is written. +pub enum Language { + Ink, + Solidity, + AssemblyScript, + Other(&'static str), +} + +/// The compilers used to compile a smart contract. +// todo: custom serialize e.g. `ink! v0.3.0 (rustc 1.41.0)` +#[derive(Debug, Serialize)] +pub struct SourceCompiler { + high_level: CompilerInfo, + low_level: CompilerInfo, +} + +impl SourceCompiler { + /// Constructs a new SourceCompiler. + pub fn new(high_level: CompilerInfo, low_level: CompilerInfo) -> Self { + SourceCompiler { high_level, low_level } + } +} + +/// A compiler used to compile a smart contract. +pub struct CompilerInfo { + compiler: Compiler, + version: Version, +} + +/// Compilers used to compile a smart contract. +pub enum Compiler { + Ink, + RustC, + Solang, + LLVM, +} + +/// Metadata about a smart contract. +#[derive(Debug, Serialize)] +pub struct InkProjectContract { + name: String, + version: Version, + authors: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + description: Option, + #[serde(skip_serializing_if = "Option::is_none")] + documentation: Option, + #[serde(skip_serializing_if = "Option::is_none")] + repository: Option, + #[serde(skip_serializing_if = "Option::is_none")] + homepage: Option, + #[serde(skip_serializing_if = "Option::is_none")] + license: Option, +} + +impl InkProjectContract { + /// Constructs a new InkProjectContractBuilder. + pub fn build() -> InkProjectContractBuilder, Missing, Missing> { + InkProjectContractBuilder { + contract: Self { + name: Default::default(), + version: Version::new(0, 0, 0), + authors: vec![], + description: None, + documentation: None, + repository: None, + homepage: None, + license: None + }, + marker: Default::default() + } + } +} + +/// The license of a smart contract. +pub enum License { + SpdxId(String), + Link(Url), +} + +/// Additional user defined metadata, can be any valid json. +#[derive(Debug, Serialize)] +pub struct InkProjectUser { + #[serde(flatten)] + json: serde_json::Map +} + +impl InkProjectUser { + /// Constructs a new InkProjectUser + pub fn new(json: Map) -> Self { + InkProjectUser { json } + } +} + +/// Type state for builders to tell that some mandatory state has not yet been set +/// yet or to fail upon setting the same state multiple times. +pub struct Missing(PhantomData S>); + +mod state { + //! Type states that tell what state of the project metadata has not + //! yet been set properly for a valid construction. + + /// Type state for the name of the project. + pub struct Name; + + /// Type state for the version of the project. + pub struct Version; + + /// Type state for the authors of the project. + pub struct Authors; +} + +pub struct InkProjectContractBuilder { + contract: InkProjectContract, + marker: PhantomData (Name, Version, Authors)> +} + +impl InkProjectContractBuilder, V, A> { + pub fn name(self, name: S) -> InkProjectMetadataBuilder + where + S: AsRef + { + InkProjectMetadataBuilder { + metadata: InkProjectMetadata { + name: name.as_ref().to_owned(), + ..self.contract + }, + marker: PhantomData, + } + } +} + +impl InkProjectContractBuilder, A> { + pub fn version(self, version: Version) -> InkProjectMetadataBuilder { + InkProjectMetadataBuilder { + metadata: InkProjectMetadata { + version, + ..self.contract + }, + marker: PhantomData, + } + } +} + +impl InkProjectContractBuilder> { + pub fn authors(self, authors: I) -> InkProjectMetadataBuilder + where + I: IntoIterator, + S: AsRef + { + InkProjectMetadataBuilder { + metadata: InkProjectMetadata { + authors: authors.into_iter().map(Into::into).collect(), + ..self.contract + }, + marker: PhantomData, + } + } +} + +impl InkProjectMetadataBuilder { + fn done(self) -> InkProjectMetadata { + self.metadata + } +} diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 2ae1a9b2ee5..94c387ef785 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -21,17 +21,15 @@ extern crate alloc; mod tests; pub mod layout2; -mod project; +mod extension; mod specs; mod utils; -pub use self::project::{ - InkProject, +pub use self::extension::{ InkProjectExtension, InkProjectSource, InkProjectContract, InkProjectUser, - InkProjectSpec, }; pub use self::specs::{ ConstructorSpec, @@ -51,4 +49,58 @@ pub use self::specs::{ TypeSpec, }; +#[cfg(feature = "derive")] +use scale_info::{ + form::CompactForm, + IntoCompact as _, + Registry, +}; +use serde::Serialize; + const METADATA_VERSION: &str = "0.1.0"; + +/// An entire ink! project for ABI file generation purposes. +#[derive(Debug, Serialize)] +pub struct InkProject { + metadata_version: semver::Version, + #[serde(flatten)] + extension: InkProjectExtension, + spec: InkProjectSpec, +} + +impl InkProject { + pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { + let metadata_version= semver::Version::parse(METADATA_VERSION) + .expect("METADATA_VERSION is a valid semver string"); + InkProject { + metadata_version, + extension, + spec + } + } +} + +#[derive(Debug, Serialize)] +pub struct InkProjectSpec { + #[serde(flatten)] + registry: Registry, + #[serde(rename = "storage")] + layout: layout2::Layout, + spec: ContractSpec, +} + +impl InkProjectSpec { + /// Creates a new ink! project. + pub fn new(layout: L, spec: S) -> Self + where + L: Into, + S: Into, + { + let mut registry = Registry::new(); + Self { + layout: layout.into().into_compact(&mut registry), + spec: spec.into().into_compact(&mut registry), + registry, + } + } +} diff --git a/metadata/src/project.rs b/metadata/src/project.rs deleted file mode 100644 index 8c13928e7d3..00000000000 --- a/metadata/src/project.rs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use core::marker::PhantomData; -#[cfg(feature = "derive")] -use scale_info::{ - form::CompactForm, - IntoCompact as _, - Registry, -}; -use semver::Version; -use serde::Serialize; -use url::Url; -use super::{ - ContractSpec, - layout2, - METADATA_VERSION -}; - -/// An entire ink! project for ABI file generation purposes. -#[derive(Debug, Serialize)] -pub struct InkProject { - metadata_version: Version, - #[serde(flatten)] - extension: InkProjectExtension, - spec: InkProjectSpec, -} - -impl InkProject { - pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { - let metadata_version= Version::parse(METADATA_VERSION).expect("METADATA_VERSION is a valid semver string"); - InkProject { - metadata_version, - extension, - spec - } - } -} - -/// Additional metadata supplied externally, e.g. by a tool such as `cargo-contract` -#[derive(Debug, Serialize)] -pub struct InkProjectExtension { - source: InkProjectSource, - contract: InkProjectContract, - user: InkProjectUser, -} - -#[derive(Debug, Serialize)] -pub struct InkProjectSource { - hash: &'static str, - language: &'static str, - compiler: &'static str, -} - -#[derive(Debug, Serialize)] -pub struct InkProjectContract { - name: &'static str, - version: Version, - authors: Vec<&'static str>, - description: &'static str, - documentation: Url, - repository: Url, - homepage: Url, - license: &'static str, -} - -#[derive(Debug, Serialize)] -pub struct InkProjectUser { - #[serde(flatten)] - json: serde_json::Map -} - -impl From> for InkProjectMetadata { - fn from(builder: InkProjectMetadataBuilder) -> Self { - builder.done() - } -} - -#[derive(Debug, Serialize)] -pub struct InkProjectSpec { - #[serde(flatten)] // should result in a only a "types" field - registry: Registry, - #[serde(rename = "storage")] - layout: layout2::Layout, - spec: ContractSpec, -} - -impl InkProjectSpec { - /// Creates a new ink! project. - pub fn new(layout: L, spec: S) -> Self - where - L: Into, - S: Into, - { - let mut registry = Registry::new(); - Self { - layout: layout.into().into_compact(&mut registry), - spec: spec.into().into_compact(&mut registry), - registry, - } - } -} - -/// Type state for builders to tell that some mandatory state has not yet been set -/// yet or to fail upon setting the same state multiple times. -pub struct Missing(PhantomData S>); - -mod state { - //! Type states that tell what state of the project metadata has not - //! yet been set properly for a valid construction. - - /// Type state for the version of the project metadata. - pub struct Version; -} - -pub struct InkProjectMetadataBuilder { - metadata: InkProjectMetadata, - marker: PhantomData (Version)> -} - -impl InkProjectMetadataBuilder> { - // todo: error type? - pub fn version(self, version: S) -> Result, ()> { - let version = Version::parse(version.as_ref()).map_err(|_| ())?; - Ok(InkProjectMetadataBuilder { - metadata: InkProjectMetadata { - version, - ..self.metadata - }, - marker: PhantomData, - }) - } -} - -impl InkProjectMetadataBuilder { - fn done(self) -> InkProjectMetadata { - self.metadata - } -} From 0f5765a6566f1c07c0aef18dbf8b5e5efafc0312 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 2 Jul 2020 14:50:22 +0100 Subject: [PATCH 06/39] Compiles...ship it --- lang/macro/src/codegen/metadata.rs | 2 +- metadata/src/extension.rs | 34 ++++++++++++++++++------------ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 30a838322b0..36b8603a11d 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -27,7 +27,7 @@ use crate::{ /// Generates code to generate the metadata of the contract. #[derive(From)] -pub struct l<'a> { +pub struct GenerateMetadata<'a> { /// The contract to generate code for. contract: &'a ir::Contract, } diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 7d6bde3be7c..564ef3d0df4 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -64,6 +64,7 @@ impl SourceLanguage { } /// The language in which the smart contract is written. +#[derive(Debug, Serialize)] pub enum Language { Ink, Solidity, @@ -87,12 +88,14 @@ impl SourceCompiler { } /// A compiler used to compile a smart contract. +#[derive(Debug, Serialize)] pub struct CompilerInfo { compiler: Compiler, version: Version, } /// Compilers used to compile a smart contract. +#[derive(Debug, Serialize)] pub enum Compiler { Ink, RustC, @@ -137,9 +140,12 @@ impl InkProjectContract { } } -/// The license of a smart contract. +/// The license of a smart contract +#[derive(Debug, Serialize)] pub enum License { + /// An [SPDX identifier](https://spdx.org/licenses/) SpdxId(String), + /// A URL to a custom license Link(Url), } @@ -181,12 +187,12 @@ pub struct InkProjectContractBuilder { } impl InkProjectContractBuilder, V, A> { - pub fn name(self, name: S) -> InkProjectMetadataBuilder + pub fn name(self, name: S) -> InkProjectContractBuilder where S: AsRef { - InkProjectMetadataBuilder { - metadata: InkProjectMetadata { + InkProjectContractBuilder { + contract: InkProjectContract { name: name.as_ref().to_owned(), ..self.contract }, @@ -196,9 +202,9 @@ impl InkProjectContractBuilder, V, A> { } impl InkProjectContractBuilder, A> { - pub fn version(self, version: Version) -> InkProjectMetadataBuilder { - InkProjectMetadataBuilder { - metadata: InkProjectMetadata { + pub fn version(self, version: Version) -> InkProjectContractBuilder { + InkProjectContractBuilder { + contract: InkProjectContract { version, ..self.contract }, @@ -208,14 +214,14 @@ impl InkProjectContractBuilder, A> { } impl InkProjectContractBuilder> { - pub fn authors(self, authors: I) -> InkProjectMetadataBuilder + pub fn authors(self, authors: I) -> InkProjectContractBuilder where I: IntoIterator, S: AsRef { - InkProjectMetadataBuilder { - metadata: InkProjectMetadata { - authors: authors.into_iter().map(Into::into).collect(), + InkProjectContractBuilder { + contract: InkProjectContract { + authors: authors.into_iter().map(|s| s.as_ref().into()).collect(), ..self.contract }, marker: PhantomData, @@ -223,8 +229,8 @@ impl InkProjectContractBuilder> { } } -impl InkProjectMetadataBuilder { - fn done(self) -> InkProjectMetadata { - self.metadata +impl InkProjectContractBuilder { + fn done(self) -> InkProjectContract { + self.contract } } From 3016a3e5722a53b38b18f11f4dbb757912cb09b7 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 2 Jul 2020 14:51:24 +0100 Subject: [PATCH 07/39] Fmt --- metadata/src/extension.rs | 62 +++++++++++++++++++++++++++++---------- metadata/src/lib.rs | 58 ++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 43 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 564ef3d0df4..25c3f6f2826 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -15,7 +15,10 @@ use core::marker::PhantomData; use semver::Version; use serde::Serialize; -use serde_json::{Map, Value}; +use serde_json::{ + Map, + Value, +}; use url::Url; /// Additional metadata supplied externally, e.g. by `cargo-contract`. @@ -29,8 +32,16 @@ pub struct InkProjectExtension { impl InkProjectExtension { /// Constructs a new InkProjectExtension. - pub fn new(source: InkProjectSource, contract: InkProjectContract, user: Option) -> Self { - InkProjectExtension { source, contract, user } + pub fn new( + source: InkProjectSource, + contract: InkProjectContract, + user: Option, + ) -> Self { + InkProjectExtension { + source, + contract, + user, + } } } @@ -43,8 +54,16 @@ pub struct InkProjectSource { impl InkProjectSource { /// Constructs a new InkProjectSource. - pub fn new(hash: [u8; 32], language: SourceLanguage, compiler: SourceCompiler) -> Self { - InkProjectSource { hash, language, compiler } + pub fn new( + hash: [u8; 32], + language: SourceLanguage, + compiler: SourceCompiler, + ) -> Self { + InkProjectSource { + hash, + language, + compiler, + } } } @@ -83,7 +102,10 @@ pub struct SourceCompiler { impl SourceCompiler { /// Constructs a new SourceCompiler. pub fn new(high_level: CompilerInfo, low_level: CompilerInfo) -> Self { - SourceCompiler { high_level, low_level } + SourceCompiler { + high_level, + low_level, + } } } @@ -123,7 +145,11 @@ pub struct InkProjectContract { impl InkProjectContract { /// Constructs a new InkProjectContractBuilder. - pub fn build() -> InkProjectContractBuilder, Missing, Missing> { + pub fn build() -> InkProjectContractBuilder< + Missing, + Missing, + Missing, + > { InkProjectContractBuilder { contract: Self { name: Default::default(), @@ -133,9 +159,9 @@ impl InkProjectContract { documentation: None, repository: None, homepage: None, - license: None + license: None, }, - marker: Default::default() + marker: Default::default(), } } } @@ -153,7 +179,7 @@ pub enum License { #[derive(Debug, Serialize)] pub struct InkProjectUser { #[serde(flatten)] - json: serde_json::Map + json: serde_json::Map, } impl InkProjectUser { @@ -183,13 +209,13 @@ mod state { pub struct InkProjectContractBuilder { contract: InkProjectContract, - marker: PhantomData (Name, Version, Authors)> + marker: PhantomData (Name, Version, Authors)>, } impl InkProjectContractBuilder, V, A> { pub fn name(self, name: S) -> InkProjectContractBuilder where - S: AsRef + S: AsRef, { InkProjectContractBuilder { contract: InkProjectContract { @@ -202,7 +228,10 @@ impl InkProjectContractBuilder, V, A> { } impl InkProjectContractBuilder, A> { - pub fn version(self, version: Version) -> InkProjectContractBuilder { + pub fn version( + self, + version: Version, + ) -> InkProjectContractBuilder { InkProjectContractBuilder { contract: InkProjectContract { version, @@ -214,10 +243,13 @@ impl InkProjectContractBuilder, A> { } impl InkProjectContractBuilder> { - pub fn authors(self, authors: I) -> InkProjectContractBuilder + pub fn authors( + self, + authors: I, + ) -> InkProjectContractBuilder where I: IntoIterator, - S: AsRef + S: AsRef, { InkProjectContractBuilder { contract: InkProjectContract { diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 94c387ef785..e89428e099b 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -20,33 +20,35 @@ extern crate alloc; #[cfg(test)] mod tests; -pub mod layout2; mod extension; +pub mod layout2; mod specs; mod utils; -pub use self::extension::{ - InkProjectExtension, - InkProjectSource, - InkProjectContract, - InkProjectUser, -}; -pub use self::specs::{ - ConstructorSpec, - ConstructorSpecBuilder, - ContractSpec, - ContractSpecBuilder, - DisplayName, - EventParamSpec, - EventParamSpecBuilder, - EventSpec, - EventSpecBuilder, - MessageParamSpec, - MessageParamSpecBuilder, - MessageSpec, - MessageSpecBuilder, - ReturnTypeSpec, - TypeSpec, +pub use self::{ + extension::{ + InkProjectContract, + InkProjectExtension, + InkProjectSource, + InkProjectUser, + }, + specs::{ + ConstructorSpec, + ConstructorSpecBuilder, + ContractSpec, + ContractSpecBuilder, + DisplayName, + EventParamSpec, + EventParamSpecBuilder, + EventSpec, + EventSpecBuilder, + MessageParamSpec, + MessageParamSpecBuilder, + MessageSpec, + MessageSpecBuilder, + ReturnTypeSpec, + TypeSpec, + }, }; #[cfg(feature = "derive")] @@ -70,12 +72,12 @@ pub struct InkProject { impl InkProject { pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { - let metadata_version= semver::Version::parse(METADATA_VERSION) + let metadata_version = semver::Version::parse(METADATA_VERSION) .expect("METADATA_VERSION is a valid semver string"); InkProject { metadata_version, extension, - spec + spec, } } } @@ -92,9 +94,9 @@ pub struct InkProjectSpec { impl InkProjectSpec { /// Creates a new ink! project. pub fn new(layout: L, spec: S) -> Self - where - L: Into, - S: Into, + where + L: Into, + S: Into, { let mut registry = Registry::new(); Self { From 9a460a51766edde565adec999fd7617067d4b8c1 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 09:46:23 +0100 Subject: [PATCH 08/39] Add optional fields and doc test --- metadata/src/extension.rs | 74 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 25c3f6f2826..ed038b6a0f8 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -116,6 +116,12 @@ pub struct CompilerInfo { version: Version, } +impl CompilerInfo { + pub fn new(compiler: Compiler, version: Version) -> Self { + CompilerInfo { compiler, version } + } +} + /// Compilers used to compile a smart contract. #[derive(Debug, Serialize)] pub enum Compiler { @@ -207,12 +213,41 @@ mod state { pub struct Authors; } +/// Build an [`InkProjectContract`], ensuring required fields are supplied +/// +/// # Example +/// +/// ``` +/// # use crate::ink_metadata::InkProjectContract; +/// # use semver::Version; +/// # use url::Url; +/// // contract metadata with the minimum set of required fields +/// let metadata1: InkProjectContract = +/// InkProjectContract::build() +/// .name("example") +/// .version(Version::new(0, 1, 0)) +/// .authors(vec!["author@example.com"]) +/// .done(); +/// +/// // contract metadata with optional fields +/// let metadata2: InkProjectContract = +/// InkProjectContract::build() +/// .name("example") +/// .version(Version::new(0, 1, 0)) +/// .authors(vec!["author@example.com"]) +/// .description("description") +/// .documentation(Url::parse("http://example.com").unwrap()) +/// .repository(Url::parse("http://example.com").unwrap()) +/// .homepage(Url::parse("http://example.com").unwrap()) +/// .done(); +/// ``` pub struct InkProjectContractBuilder { contract: InkProjectContract, marker: PhantomData (Name, Version, Authors)>, } impl InkProjectContractBuilder, V, A> { + /// Set the contract name (required) pub fn name(self, name: S) -> InkProjectContractBuilder where S: AsRef, @@ -228,6 +263,7 @@ impl InkProjectContractBuilder, V, A> { } impl InkProjectContractBuilder, A> { + /// Set the contract version (required) pub fn version( self, version: Version, @@ -243,6 +279,7 @@ impl InkProjectContractBuilder, A> { } impl InkProjectContractBuilder> { + /// Set the contract authors (required) pub fn authors( self, authors: I, @@ -261,8 +298,43 @@ impl InkProjectContractBuilder> { } } +impl InkProjectContractBuilder { + /// Set the contract description (optional) + pub fn description(mut self, description: S) -> Self + where + S: AsRef + { + self.contract.description = Some(description.as_ref().to_owned()); + self + } + + /// Set the contract documentation url (optional) + pub fn documentation(mut self, documentation: Url) -> Self { + self.contract.documentation = Some(documentation); + self + } + + /// Set the contract documentation url (optional) + pub fn repository(mut self, repository: Url) -> Self { + self.contract.repository = Some(repository); + self + } + + /// Set the contract homepage url (optional) + pub fn homepage(mut self, homepage: Url) -> Self { + self.contract.homepage = Some(homepage); + self + } + + /// Set the contract license (optional) + pub fn license(mut self, license: License) -> Self { + self.contract.license = Some(license); + self + } +} + impl InkProjectContractBuilder { - fn done(self) -> InkProjectContract { + pub fn done(self) -> InkProjectContract { self.contract } } From 27fd633354f9da5320c75def961d179949ad72a8 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 10:19:29 +0100 Subject: [PATCH 09/39] Add custom serializer impls for compiler/lang --- metadata/src/extension.rs | 55 +++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index ed038b6a0f8..baa5d7a419d 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -12,9 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +use core::fmt::{Display, Formatter, Result as DisplayResult}; use core::marker::PhantomData; use semver::Version; -use serde::Serialize; +use serde::{Serialize, Serializer}; use serde_json::{ Map, Value, @@ -68,8 +69,7 @@ impl InkProjectSource { } /// The language and version in which a smart contract is written. -// todo: custom serialize e.g. `ink! v0.3.0` -#[derive(Debug, Serialize)] +#[derive(Debug)] pub struct SourceLanguage { language: Language, version: Version, @@ -82,8 +82,14 @@ impl SourceLanguage { } } +impl Serialize for SourceLanguage { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&format!("{} {}", self.language, self.version)) + } +} + /// The language in which the smart contract is written. -#[derive(Debug, Serialize)] +#[derive(Debug)] pub enum Language { Ink, Solidity, @@ -91,14 +97,30 @@ pub enum Language { Other(&'static str), } +impl Display for Language { + fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { + match self { + Self::Ink => write!(f, "ink!"), + Self::Solidity => write!(f, "Solidity"), + Self::AssemblyScript => write!(f, "AssemblyScript"), + Self::Other(lang) => write!(f, "{}", lang), + } + } +} + /// The compilers used to compile a smart contract. -// todo: custom serialize e.g. `ink! v0.3.0 (rustc 1.41.0)` -#[derive(Debug, Serialize)] +#[derive(Debug)] pub struct SourceCompiler { high_level: CompilerInfo, low_level: CompilerInfo, } +impl Serialize for SourceCompiler { + fn serialize(&self, serializer: S) -> Result where S: Serializer { + serializer.serialize_str(&format!("{} ({})", self.high_level, self.low_level)) + } +} + impl SourceCompiler { /// Constructs a new SourceCompiler. pub fn new(high_level: CompilerInfo, low_level: CompilerInfo) -> Self { @@ -110,12 +132,18 @@ impl SourceCompiler { } /// A compiler used to compile a smart contract. -#[derive(Debug, Serialize)] +#[derive(Debug)] pub struct CompilerInfo { compiler: Compiler, version: Version, } +impl Display for CompilerInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { + write!(f, "{} {}", self.compiler, self.version) + } +} + impl CompilerInfo { pub fn new(compiler: Compiler, version: Version) -> Self { CompilerInfo { compiler, version } @@ -131,6 +159,17 @@ pub enum Compiler { LLVM, } +impl Display for Compiler { + fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { + match self { + Self::Ink => write!(f, "ink!"), + Self::RustC => write!(f, "rustc"), + Self::Solang => write!(f, "solang"), + Self::LLVM => write!(f, "llvm"), + } + } +} + /// Metadata about a smart contract. #[derive(Debug, Serialize)] pub struct InkProjectContract { @@ -302,7 +341,7 @@ impl InkProjectContractBuilder { /// Set the contract description (optional) pub fn description(mut self, description: S) -> Self where - S: AsRef + S: AsRef, { self.contract.description = Some(description.as_ref().to_owned()); self From 3698478a24d7c305f9642b9833232c59db9fa5e6 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 10:20:06 +0100 Subject: [PATCH 10/39] Fmt --- metadata/src/extension.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index baa5d7a419d..4e700297142 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -12,10 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -use core::fmt::{Display, Formatter, Result as DisplayResult}; -use core::marker::PhantomData; +use core::{ + fmt::{ + Display, + Formatter, + Result as DisplayResult, + }, + marker::PhantomData, +}; use semver::Version; -use serde::{Serialize, Serializer}; +use serde::{ + Serialize, + Serializer, +}; use serde_json::{ Map, Value, @@ -83,7 +92,10 @@ impl SourceLanguage { } impl Serialize for SourceLanguage { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { serializer.serialize_str(&format!("{} {}", self.language, self.version)) } } @@ -116,7 +128,10 @@ pub struct SourceCompiler { } impl Serialize for SourceCompiler { - fn serialize(&self, serializer: S) -> Result where S: Serializer { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { serializer.serialize_str(&format!("{} ({})", self.high_level, self.low_level)) } } From eb1e923f6cba6f642639b66a0c6223e20a9c1f75 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 10:21:46 +0100 Subject: [PATCH 11/39] Clippy --- metadata/src/extension.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 4e700297142..76f425e831e 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -295,6 +295,7 @@ mod state { /// .homepage(Url::parse("http://example.com").unwrap()) /// .done(); /// ``` +#[allow(clippy::type_complexity)] pub struct InkProjectContractBuilder { contract: InkProjectContract, marker: PhantomData (Name, Version, Authors)>, From 89eb9f36f91ead35f428d82493b80ddff6420b43 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 11:14:12 +0100 Subject: [PATCH 12/39] Update to scale-info 0.3 --- core/Cargo.toml | 2 +- examples/delegator/Cargo.toml | 2 +- examples/delegator/accumulator/Cargo.toml | 2 +- examples/delegator/adder/Cargo.toml | 2 +- examples/delegator/subber/Cargo.toml | 2 +- examples/dns/Cargo.toml | 2 +- examples/erc20/Cargo.toml | 2 +- examples/erc721/Cargo.toml | 2 +- examples/flipper/Cargo.toml | 2 +- examples/incrementer/Cargo.toml | 2 +- examples/multisig_plain/Cargo.toml | 2 +- examples/runtime-storage/Cargo.toml | 2 +- lang/macro/Cargo.toml | 2 +- metadata/Cargo.toml | 2 +- primitives/Cargo.toml | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 9e8a7a66c64..324bfded109 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -39,7 +39,7 @@ blake2 = { version = "0.9", optional = true } # Sadly couldn't be marked as dev-dependency. # Never use this crate outside of the off-chain environment! rand = { version = "0.7", default-features = false, features = ["alloc"], optional = true } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } # Workaround: we actually just need criterion as a dev-dependency, but # there is an issue with a doubly included std lib when executing diff --git a/examples/delegator/Cargo.toml b/examples/delegator/Cargo.toml index a8c0d7a700c..910e1828ea0 100644 --- a/examples/delegator/Cargo.toml +++ b/examples/delegator/Cargo.toml @@ -15,7 +15,7 @@ scale = { package = "parity-scale-codec", version = "1.3", default-features = fa adder = { version = "2.1.0", path = "adder", default-features = false, features = ["ink-as-dependency"] } subber = { version = "2.1.0", path = "subber", default-features = false, features = ["ink-as-dependency"] } accumulator = { version = "2.1.0", path = "accumulator", default-features = false, features = ["ink-as-dependency"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "delegator" diff --git a/examples/delegator/accumulator/Cargo.toml b/examples/delegator/accumulator/Cargo.toml index c73e3ca040b..22546b14a96 100644 --- a/examples/delegator/accumulator/Cargo.toml +++ b/examples/delegator/accumulator/Cargo.toml @@ -11,7 +11,7 @@ ink_core = { version = "2.1.0", path = "../../../core", default-features = false ink_lang = { version = "2.1.0", path = "../../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "accumulator" diff --git a/examples/delegator/adder/Cargo.toml b/examples/delegator/adder/Cargo.toml index 0927aabbced..4199434d73a 100644 --- a/examples/delegator/adder/Cargo.toml +++ b/examples/delegator/adder/Cargo.toml @@ -13,7 +13,7 @@ ink_lang = { version = "2.1.0", path = "../../../lang", default-features = false accumulator = { version = "2.1.0", path = "../accumulator", default-features = false, features = ["ink-as-dependency"] } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "adder" diff --git a/examples/delegator/subber/Cargo.toml b/examples/delegator/subber/Cargo.toml index fd871993eb1..ac1afb3b520 100644 --- a/examples/delegator/subber/Cargo.toml +++ b/examples/delegator/subber/Cargo.toml @@ -13,7 +13,7 @@ ink_lang = { version = "2.1.0", path = "../../../lang", default-features = false accumulator = { version = "2.1.0", path = "../accumulator", default-features = false, features = ["ink-as-dependency"] } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "subber" diff --git a/examples/dns/Cargo.toml b/examples/dns/Cargo.toml index e0b2251b733..ebfea57bb08 100644 --- a/examples/dns/Cargo.toml +++ b/examples/dns/Cargo.toml @@ -11,7 +11,7 @@ ink_core = { version = "2.1.0", path = "../../core", default-features = false } ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "dns" diff --git a/examples/erc20/Cargo.toml b/examples/erc20/Cargo.toml index 278adafc2f1..e3faa083a4c 100644 --- a/examples/erc20/Cargo.toml +++ b/examples/erc20/Cargo.toml @@ -11,7 +11,7 @@ ink_core = { version = "2.1.0", path = "../../core", default-features = false } ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "erc20" diff --git a/examples/erc721/Cargo.toml b/examples/erc721/Cargo.toml index 1ecbfc7b799..0be4ddcdf19 100644 --- a/examples/erc721/Cargo.toml +++ b/examples/erc721/Cargo.toml @@ -11,7 +11,7 @@ ink_core = { version = "2.1.0", path = "../../core", default-features = false } ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "erc721" diff --git a/examples/flipper/Cargo.toml b/examples/flipper/Cargo.toml index bd9b30bd252..7b71ec0d6aa 100644 --- a/examples/flipper/Cargo.toml +++ b/examples/flipper/Cargo.toml @@ -11,7 +11,7 @@ ink_core = { version = "2.1.0", path = "../../core", default-features = false } ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "flipper" diff --git a/examples/incrementer/Cargo.toml b/examples/incrementer/Cargo.toml index 6eae4916db6..4e430362190 100644 --- a/examples/incrementer/Cargo.toml +++ b/examples/incrementer/Cargo.toml @@ -11,7 +11,7 @@ ink_core = { version = "2.1.0", path = "../../core", default-features = false } ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "incrementer" diff --git a/examples/multisig_plain/Cargo.toml b/examples/multisig_plain/Cargo.toml index d93ec43c2f2..3fa9aa649b6 100755 --- a/examples/multisig_plain/Cargo.toml +++ b/examples/multisig_plain/Cargo.toml @@ -12,7 +12,7 @@ ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } ink_prelude = { version = "2.1.0", path = "../../prelude", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "multisig_plain" diff --git a/examples/runtime-storage/Cargo.toml b/examples/runtime-storage/Cargo.toml index 44db1bc621b..b95575d3e33 100755 --- a/examples/runtime-storage/Cargo.toml +++ b/examples/runtime-storage/Cargo.toml @@ -12,7 +12,7 @@ ink_core = { version = "2.1.0", path = "../../core", default-features = false } ink_lang = { version = "2.1.0", path = "../../lang", default-features = false } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [lib] name = "runtime_storage" diff --git a/lang/macro/Cargo.toml b/lang/macro/Cargo.toml index 91964f88023..5b1710f93bb 100644 --- a/lang/macro/Cargo.toml +++ b/lang/macro/Cargo.toml @@ -36,7 +36,7 @@ ink_lang = { version = "2.1.0", path = ".." } trybuild = "1.0.24" pretty_assertions = "0.6.1" -scale-info = { version = "0.2", default-features = false, features = ["derive"] } +scale-info = { version = "0.3", default-features = false, features = ["derive"] } [lib] name = "ink_lang_macro" diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index 0e7fb2439de..d8ef9db69d3 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -21,7 +21,7 @@ ink_primitives = { version = "2.1.0", path = "../primitives/", default-features serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } serde_json = "1.0" derive_more = { version = "0.99", default-features = false, features = ["from"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"] } +scale-info = { version = "0.3", default-features = false, features = ["derive"] } semver = { version = "0.10.0", features = ["serde"] } url = { version = "2.1.1", features = ["serde"] } diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index f8c1d2d5504..68467e3e506 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -21,7 +21,7 @@ include = ["/Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] ink_prelude = { version = "2.1.0", path = "../prelude/", default-features = false } tiny-keccak = { version = "2.0", features = ["keccak"] } scale = { package = "parity-scale-codec", version = "1.3", default-features = false, features = ["derive", "full"] } -scale-info = { version = "0.2", default-features = false, features = ["derive"], optional = true } +scale-info = { version = "0.3", default-features = false, features = ["derive"], optional = true } [dev-dependencies] criterion = "0.3.1" From 46f7d6074fc6b4a68140a89486cdb42e1cd42589 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 11:56:00 +0100 Subject: [PATCH 13/39] Use &'static str instead of compact string (scale-info 0.3) --- metadata/src/layout2/mod.rs | 6 +++--- metadata/src/specs.rs | 38 ++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/metadata/src/layout2/mod.rs b/metadata/src/layout2/mod.rs index fe2cdfae8bb..b475a2528d4 100644 --- a/metadata/src/layout2/mod.rs +++ b/metadata/src/layout2/mod.rs @@ -300,7 +300,7 @@ pub struct FieldLayout { /// The name of the field. /// /// Can be missing, e.g. in case of an enum tuple struct variant. - name: Option, + name: Option<&'static str>, /// The kind of the field. /// /// This is either a direct layout bound @@ -312,7 +312,7 @@ impl FieldLayout { /// Creates a new field layout. pub fn new(name: N, layout: L) -> Self where - N: Into::String>>, + N: Into>, L: Into, { Self { @@ -327,7 +327,7 @@ impl IntoCompact for FieldLayout { fn into_compact(self, registry: &mut Registry) -> Self::Output { FieldLayout { - name: self.name.map(|name| registry.register_string(name)), + name: self.name, layout: self.layout.into_compact(registry), } } diff --git a/metadata/src/specs.rs b/metadata/src/specs.rs index cdd8cdb25cf..75e6e8a9a2e 100644 --- a/metadata/src/specs.rs +++ b/metadata/src/specs.rs @@ -40,7 +40,7 @@ use serde::Serialize; #[serde(bound = "F::TypeId: Serialize")] pub struct ContractSpec { /// The name of the contract. - name: F::String, + name: &'static str, /// The set of constructors of the contract. constructors: Vec>, /// The external messages of the contract. @@ -56,7 +56,7 @@ impl IntoCompact for ContractSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { ContractSpec { - name: registry.register_string(&self.name), + name: self.name, constructors: self .constructors .into_iter() @@ -171,7 +171,7 @@ impl ContractSpecBuilder { impl ContractSpec { /// Creates a new contract specification. - pub fn new(name: ::String) -> ContractSpecBuilder { + pub fn new(name: &'static str) -> ContractSpecBuilder { ContractSpecBuilder { spec: Self { name, @@ -190,7 +190,7 @@ impl ContractSpec { #[serde(bound = "F::TypeId: Serialize")] pub struct ConstructorSpec { /// The name of the message. - name: F::String, + name: &'static str, /// The selector hash of the message. #[serde(serialize_with = "serialize_as_byte_str")] selector: [u8; 4], @@ -205,7 +205,7 @@ impl IntoCompact for ConstructorSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { ConstructorSpec { - name: registry.register_string(&self.name), + name: self.name, selector: self.selector, args: self .args @@ -232,7 +232,7 @@ pub struct ConstructorSpecBuilder { impl ConstructorSpec { /// Creates a new constructor spec builder. pub fn new( - name: ::String, + name: &'static str, ) -> ConstructorSpecBuilder> { ConstructorSpecBuilder { spec: Self { @@ -296,7 +296,7 @@ impl ConstructorSpecBuilder { #[serde(rename_all = "camelCase")] pub struct MessageSpec { /// The name of the message. - name: F::String, + name: &'static str, /// The selector hash of the message. #[serde(serialize_with = "serialize_as_byte_str")] selector: [u8; 4], @@ -329,7 +329,7 @@ mod state { impl MessageSpec { /// Creates a new message spec builder. pub fn new( - name: ::String, + name: &'static str, ) -> MessageSpecBuilder< Missing, Missing, @@ -443,7 +443,7 @@ impl IntoCompact for MessageSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { MessageSpec { - name: registry.register_string(&self.name), + name: self.name, selector: self.selector, mutates: self.mutates, args: self @@ -462,7 +462,7 @@ impl IntoCompact for MessageSpec { #[serde(bound = "F::TypeId: Serialize")] pub struct EventSpec { /// The name of the event. - name: F::String, + name: &'static str, /// The event arguments. args: Vec>, /// The event documentation. @@ -508,7 +508,7 @@ impl IntoCompact for EventSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { EventSpec { - name: registry.register_string(&self.name), + name: self.name, args: self .args .into_iter() @@ -549,7 +549,7 @@ impl EventSpec { /// default setup. Even though it would be useful for third party tools /// such as the Polkadot UI to know that we are handling with `Balance` /// types, we currently cannot communicate this without display names. -pub type DisplayName = scale_info::Path; +pub type DisplayName = scale_info::Path; /// A type specification. /// @@ -575,7 +575,7 @@ pub struct TypeSpec { /// The actual type. id: F::TypeId, /// The compile-time known displayed representation of the type. - display_name: DisplayName, + display_name: DisplayName, } impl IntoCompact for TypeSpec { @@ -584,7 +584,7 @@ impl IntoCompact for TypeSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { TypeSpec { id: registry.register_type(&self.id), - display_name: self.display_name.into_compact(registry), + display_name: self.display_name, } } } @@ -623,7 +623,7 @@ impl TypeSpec { pub fn with_name_segs(segments: S) -> Self where T: TypeInfo + 'static, - S: IntoIterator::String>, + S: IntoIterator, { Self { id: meta_type::(), @@ -649,7 +649,7 @@ impl TypeSpec { #[serde(bound = "F::TypeId: Serialize")] pub struct EventParamSpec { /// The name of the parameter. - name: F::String, + name: &'static str, /// If the event parameter is indexed. indexed: bool, /// The type of the parameter. @@ -664,7 +664,7 @@ impl IntoCompact for EventParamSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { EventParamSpec { - name: registry.register_string(self.name), + name: self.name, indexed: self.indexed, ty: self.ty.into_compact(registry), docs: self.docs, @@ -776,7 +776,7 @@ impl ReturnTypeSpec { #[serde(bound = "F::TypeId: Serialize")] pub struct MessageParamSpec { /// The name of the parameter. - name: F::String, + name: &'static str, /// The type of the parameter. #[serde(rename = "type")] ty: TypeSpec, @@ -787,7 +787,7 @@ impl IntoCompact for MessageParamSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { MessageParamSpec { - name: registry.register_string(self.name), + name: self.name, ty: self.ty.into_compact(registry), } } From 9278ea20855c6b5da93dc2e9778aaa1f74920796 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 11:57:32 +0100 Subject: [PATCH 14/39] Reexport Url and Version --- metadata/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index e89428e099b..e3341afc37c 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -25,6 +25,9 @@ pub mod layout2; mod specs; mod utils; +pub use url::Url; +pub use semver::Version; + pub use self::{ extension::{ InkProjectContract, From 3f5d65f0fde2964564926894cb0d89412f8a54ca Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 15:28:06 +0100 Subject: [PATCH 15/39] Fix missing semicolon --- lang/macro/src/codegen/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 36b8603a11d..5de9aaf40dc 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -49,7 +49,7 @@ impl GenerateCode for GenerateMetadata<'_> { let layout: ::ink_metadata::layout2::Layout = { #layout }; - let spec = ::ink_metadata::InkSpec::new(layout, spec) + let spec = ::ink_metadata::InkSpec::new(layout, spec); ::ink_metadata::InkProject::new(extension, spec) } }; From bbc6f23b8e86bc6ffec31f684ea6b88437b47c28 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 16:09:35 +0100 Subject: [PATCH 16/39] Fix up metadata exports and codegen --- lang/macro/src/codegen/metadata.rs | 2 +- metadata/src/lib.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 5de9aaf40dc..5e950aeb5bf 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -49,7 +49,7 @@ impl GenerateCode for GenerateMetadata<'_> { let layout: ::ink_metadata::layout2::Layout = { #layout }; - let spec = ::ink_metadata::InkSpec::new(layout, spec); + let spec = ::ink_metadata::InkProjectSpec::new(layout, contract); ::ink_metadata::InkProject::new(extension, spec) } }; diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index e3341afc37c..ba375dc7db5 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -30,10 +30,16 @@ pub use semver::Version; pub use self::{ extension::{ + Compiler, + CompilerInfo, InkProjectContract, InkProjectExtension, InkProjectSource, InkProjectUser, + Language, + License, + SourceCompiler, + SourceLanguage, }, specs::{ ConstructorSpec, @@ -96,7 +102,7 @@ pub struct InkProjectSpec { impl InkProjectSpec { /// Creates a new ink! project. - pub fn new(layout: L, spec: S) -> Self + pub fn new(layout: L, spec: S) -> Self where L: Into, S: Into, From 29d58c9c0d57e893acc89f3b015328686d70084e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 16:18:22 +0100 Subject: [PATCH 17/39] Serialize hash as byte string --- metadata/src/extension.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 76f425e831e..cda2625dfe4 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::utils::serialize_as_byte_str; use core::{ fmt::{ Display, @@ -57,6 +58,7 @@ impl InkProjectExtension { #[derive(Debug, Serialize)] pub struct InkProjectSource { + #[serde(serialize_with = "serialize_as_byte_str")] hash: [u8; 32], language: SourceLanguage, compiler: SourceCompiler, From 161ae9bdaa5c94d3d36fe4f5fdaf40f6f8f020c8 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 16:48:56 +0100 Subject: [PATCH 18/39] Remove spec nesting --- lang/macro/src/codegen/metadata.rs | 3 +-- metadata/src/lib.rs | 32 ++++++++---------------------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 5e950aeb5bf..fcbdff35bc7 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -49,8 +49,7 @@ impl GenerateCode for GenerateMetadata<'_> { let layout: ::ink_metadata::layout2::Layout = { #layout }; - let spec = ::ink_metadata::InkProjectSpec::new(layout, contract); - ::ink_metadata::InkProject::new(extension, spec) + ::ink_metadata::InkProject::new(extension, layout, contract) } }; } diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index ba375dc7db5..c88e41077b7 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -76,42 +76,26 @@ pub struct InkProject { metadata_version: semver::Version, #[serde(flatten)] extension: InkProjectExtension, - spec: InkProjectSpec, -} - -impl InkProject { - pub fn new(extension: InkProjectExtension, spec: InkProjectSpec) -> Self { - let metadata_version = semver::Version::parse(METADATA_VERSION) - .expect("METADATA_VERSION is a valid semver string"); - InkProject { - metadata_version, - extension, - spec, - } - } -} - -#[derive(Debug, Serialize)] -pub struct InkProjectSpec { - #[serde(flatten)] - registry: Registry, #[serde(rename = "storage")] layout: layout2::Layout, spec: ContractSpec, } -impl InkProjectSpec { - /// Creates a new ink! project. - pub fn new(layout: L, spec: S) -> Self +impl InkProject { + pub fn new(extension: InkProjectExtension, layout: L, spec: S) -> Self where L: Into, S: Into, { + let metadata_version = semver::Version::parse(METADATA_VERSION) + .expect("METADATA_VERSION is a valid semver string"); let mut registry = Registry::new(); - Self { + + InkProject { + metadata_version, + extension, layout: layout.into().into_compact(&mut registry), spec: spec.into().into_compact(&mut registry), - registry, } } } From c68032ef3b7a26aa314699c1b245a6dbca299763 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Fri, 3 Jul 2020 16:55:57 +0100 Subject: [PATCH 19/39] Remove name from contract spec --- lang/macro/src/codegen/metadata.rs | 4 +--- metadata/src/specs.rs | 6 +----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index fcbdff35bc7..14725ababf1 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -242,15 +242,13 @@ impl GenerateMetadata<'_> { } fn generate_contract(&self) -> TokenStream2 { - let contract_ident_lit = self.contract.ident.to_string(); - let constructors = self.generate_constructors(); let messages = self.generate_messages(); let events = self.generate_events(); let docs = self.generate_docs(); quote! { - ::ink_metadata::ContractSpec::new(#contract_ident_lit) + ::ink_metadata::ContractSpec::new() .constructors(vec![ #(#constructors ,)* ]) diff --git a/metadata/src/specs.rs b/metadata/src/specs.rs index 75e6e8a9a2e..42ca28f6774 100644 --- a/metadata/src/specs.rs +++ b/metadata/src/specs.rs @@ -39,8 +39,6 @@ use serde::Serialize; #[derive(Debug, PartialEq, Eq, Serialize)] #[serde(bound = "F::TypeId: Serialize")] pub struct ContractSpec { - /// The name of the contract. - name: &'static str, /// The set of constructors of the contract. constructors: Vec>, /// The external messages of the contract. @@ -56,7 +54,6 @@ impl IntoCompact for ContractSpec { fn into_compact(self, registry: &mut Registry) -> Self::Output { ContractSpec { - name: self.name, constructors: self .constructors .into_iter() @@ -171,10 +168,9 @@ impl ContractSpecBuilder { impl ContractSpec { /// Creates a new contract specification. - pub fn new(name: &'static str) -> ContractSpecBuilder { + pub fn new() -> ContractSpecBuilder { ContractSpecBuilder { spec: Self { - name, constructors: Vec::new(), messages: Vec::new(), events: Vec::new(), From 8832d1020e572aa532731725780472fe079e8990 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 6 Jul 2020 09:28:37 +0100 Subject: [PATCH 20/39] Add name to storage struct --- lang/macro/src/codegen/metadata.rs | 11 +++++++---- metadata/src/layout2/mod.rs | 28 ++++++++++++++++++++++++++++ metadata/src/lib.rs | 4 ++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 14725ababf1..25738a3ef3d 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -46,7 +46,7 @@ impl GenerateCode for GenerateMetadata<'_> { let contract: ::ink_metadata::ContractSpec = { #contract }; - let layout: ::ink_metadata::layout2::Layout = { + let layout: ::ink_metadata::layout2::StorageLayout = { #layout }; ::ink_metadata::InkProject::new(extension, layout, contract) @@ -267,10 +267,13 @@ impl GenerateMetadata<'_> { fn generate_layout(&self) -> TokenStream2 { let contract_ident = &self.contract.storage.ident; + let contract_ident_lit = contract_ident.to_string(); quote! { - <#contract_ident as ::ink_core::storage2::traits::StorageLayout>::layout( - &mut ::ink_primitives::KeyPtr::from(::ink_primitives::Key::from([0x00; 32])) - ) + let layout = + <#contract_ident as ::ink_core::storage2::traits::StorageLayout>::layout( + &mut ::ink_primitives::KeyPtr::from(::ink_primitives::Key::from([0x00; 32])) + ); + ::ink_metadata::layout2::StorageLayout::new(#contract_ident_lit, layout) } } } diff --git a/metadata/src/layout2/mod.rs b/metadata/src/layout2/mod.rs index b475a2528d4..57e2ceb7b91 100644 --- a/metadata/src/layout2/mod.rs +++ b/metadata/src/layout2/mod.rs @@ -31,6 +31,34 @@ use scale_info::{ TypeInfo, }; +/// The name and static storage layout of an ink! smart contract +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, From, serde::Serialize)] +#[serde(bound = "F::TypeId: serde::Serialize")] +pub struct StorageLayout { + /// The name of the storage data structure + name: &'static str, + /// The layout of the storage data structure + layout: Layout, +} + +impl IntoCompact for StorageLayout { + type Output = StorageLayout; + + fn into_compact(self, registry: &mut Registry) -> Self::Output { + StorageLayout { + name: self.name, + layout: self.layout.into_compact(registry), + } + } +} + +impl StorageLayout { + /// Create a new StorageLayout with the name of the storage data structure + pub fn new(name: &'static str, layout: Layout) -> Self { + StorageLayout { name, layout } + } +} + /// Represents the static storage layout of an ink! smart contract. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, From, serde::Serialize)] #[serde(bound = "F::TypeId: serde::Serialize")] diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index c88e41077b7..492389abafc 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -77,14 +77,14 @@ pub struct InkProject { #[serde(flatten)] extension: InkProjectExtension, #[serde(rename = "storage")] - layout: layout2::Layout, + layout: layout2::StorageLayout, spec: ContractSpec, } impl InkProject { pub fn new(extension: InkProjectExtension, layout: L, spec: S) -> Self where - L: Into, + L: Into, S: Into, { let metadata_version = semver::Version::parse(METADATA_VERSION) From f33617cc814cf6ea057033dcd76b32f9ec0b716e Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 6 Jul 2020 10:14:29 +0100 Subject: [PATCH 21/39] Flatten SourceCompiler --- metadata/src/extension.rs | 37 +++++++------------------------------ metadata/src/lib.rs | 1 - 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index cda2625dfe4..63f77294964 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -122,48 +122,25 @@ impl Display for Language { } } -/// The compilers used to compile a smart contract. +/// A compiler used to compile a smart contract. #[derive(Debug)] pub struct SourceCompiler { - high_level: CompilerInfo, - low_level: CompilerInfo, + compiler: Compiler, + version: Version, } impl Serialize for SourceCompiler { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { - serializer.serialize_str(&format!("{} ({})", self.high_level, self.low_level)) + serializer.serialize_str(&format!("{} {}", self.compiler, self.version)) } } impl SourceCompiler { - /// Constructs a new SourceCompiler. - pub fn new(high_level: CompilerInfo, low_level: CompilerInfo) -> Self { - SourceCompiler { - high_level, - low_level, - } - } -} - -/// A compiler used to compile a smart contract. -#[derive(Debug)] -pub struct CompilerInfo { - compiler: Compiler, - version: Version, -} - -impl Display for CompilerInfo { - fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { - write!(f, "{} {}", self.compiler, self.version) - } -} - -impl CompilerInfo { pub fn new(compiler: Compiler, version: Version) -> Self { - CompilerInfo { compiler, version } + SourceCompiler { compiler, version } } } diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 492389abafc..3750156f4a3 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -31,7 +31,6 @@ pub use semver::Version; pub use self::{ extension::{ Compiler, - CompilerInfo, InkProjectContract, InkProjectExtension, InkProjectSource, From 6700528385306369e423df74ea8416b28370ed6a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 09:44:16 +0100 Subject: [PATCH 22/39] Implement ToTokens for Extension metadata Allows converting an instance into code that can construct that instance. For use from `cargo-contract`. --- metadata/Cargo.toml | 2 + metadata/src/extension.rs | 135 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index d8ef9db69d3..b0be9a42e7b 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -21,9 +21,11 @@ ink_primitives = { version = "2.1.0", path = "../primitives/", default-features serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } serde_json = "1.0" derive_more = { version = "0.99", default-features = false, features = ["from"] } +proc-macro2 = "1.0" scale-info = { version = "0.3", default-features = false, features = ["derive"] } semver = { version = "0.10.0", features = ["serde"] } url = { version = "2.1.1", features = ["serde"] } +quote = "1.0" [dev-dependencies] assert-json-diff = "1.0.1" diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 63f77294964..a96daaaa68a 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -21,6 +21,7 @@ use core::{ }, marker::PhantomData, }; +use proc_macro2::TokenStream; use semver::Version; use serde::{ Serialize, @@ -31,6 +32,7 @@ use serde_json::{ Value, }; use url::Url; +use quote::{quote, ToTokens, TokenStreamExt}; /// Additional metadata supplied externally, e.g. by `cargo-contract`. #[derive(Debug, Serialize)] @@ -41,6 +43,17 @@ pub struct InkProjectExtension { user: Option, } +impl ToTokens for InkProjectExtension { + fn to_tokens(&self, tokens: &mut TokenStream) { + let source = &self.source; + let user = self.user.map_or(quote!(None), ToTokens::to_token_stream); + let contract = &self.contract; + quote! ( + ::ink_metadata::InkProjectExtension::new(#source, #contract, #user) + ).to_tokens(tokens); + } +} + impl InkProjectExtension { /// Constructs a new InkProjectExtension. pub fn new( @@ -64,6 +77,17 @@ pub struct InkProjectSource { compiler: SourceCompiler, } +impl ToTokens for InkProjectSource { + fn to_tokens(&self, tokens: &mut TokenStream) { + let hash = &self.hash; + let language = &self.language; + let compiler = &self.compiler; + quote! ( + ::ink_metadata::InkProjectSource::new(#hash, #language, #compiler) + ).to_tokens(tokens); + } +} + impl InkProjectSource { /// Constructs a new InkProjectSource. pub fn new( @@ -86,6 +110,16 @@ pub struct SourceLanguage { version: Version, } +impl ToTokens for SourceLanguage { + fn to_tokens(&self, tokens: &mut TokenStream) { + let language = &self.language; + let version = &self.version; + quote! ( + ::ink_metadata::SourceLanguage::new(#language, #version) + ).to_tokens(tokens); + } +} + impl SourceLanguage { /// Constructs a new SourceLanguage. pub fn new(language: Language, version: Version) -> Self { @@ -111,6 +145,17 @@ pub enum Language { Other(&'static str), } +impl ToTokens for Language { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Self::Ink => quote! ( ::ink_metadata::Language::Ink ), + Self::Solidity => quote! ( ::ink_metadata::Language::Solidity ), + Self::AssemblyScript => quote! ( ::ink_metadata::Language::AssemblyScript ), + Self::Other(other) => quote! ( ::ink_metadata::Language::Other(#other) ), + }.to_tokens(tokens) + } +} + impl Display for Language { fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { match self { @@ -129,6 +174,16 @@ pub struct SourceCompiler { version: Version, } +impl ToTokens for SourceCompiler { + fn to_tokens(&self, tokens: &mut TokenStream) { + let compiler = &self.compiler; + let version = &self.version; + quote! ( + ::ink_metadata::SourceCompiler::new(#language, #version) + ).to_tokens(tokens); + } +} + impl Serialize for SourceCompiler { fn serialize(&self, serializer: S) -> Result where @@ -147,19 +202,27 @@ impl SourceCompiler { /// Compilers used to compile a smart contract. #[derive(Debug, Serialize)] pub enum Compiler { - Ink, RustC, Solang, - LLVM, + Other(&'static str), +} + +impl ToTokens for Compiler { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Self::RustC => quote! ( ::ink_metadata::Compiler::Solidity ), + Self::Solang => quote! ( ::ink_metadata::Compiler::AssemblyScript ), + Self::Other(other) => quote! ( ::ink_metadata::Compiler::Other(#other) ), + }.to_tokens(tokens) + } } impl Display for Compiler { fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { match self { - Self::Ink => write!(f, "ink!"), Self::RustC => write!(f, "rustc"), Self::Solang => write!(f, "solang"), - Self::LLVM => write!(f, "llvm"), + Self::Other(other) => write!(f, "other"), } } } @@ -182,6 +245,56 @@ pub struct InkProjectContract { license: Option, } +impl ToTokens for InkProjectContract { + fn to_tokens(&self, tokens: &mut TokenStream) { + let name = &self.name; + let version = self.version.to_string(); + let authors = &self.authors; + + // initialise builder with required fields + let mut builder_tokens = + quote! ( + ::ink_metadata::InkProjectContract::build() + .name(#name) + .version(::ink_metadata::Version::parse(#version).unwrap()) + .authors(vec![ + #( #authors, )* + ]) + ); + // append optional fields if present + if let Some(ref description) = self.description { + builder_tokens.append(quote!( + .description(#description) + )) + } + if let Some(ref documentation) = self.documentation { + let url_lit = documentation.to_string(); + builder_tokens.append(quote!( + .documentation(::ink_metadata::Url::parse(#url_lit).unwrap()) + )) + } + if let Some(ref repository) = self.repository { + let url_lit = repository.to_string(); + builder_tokens.append(quote!( + .repository(::ink_metadata::Url::parse(#url_lit).unwrap()) + )) + } + if let Some(ref homepage) = self.homepage { + let url_lit = homepage.to_string(); + builder_tokens.append(quote!( + .homepage(::ink_metadata::Url::parse(#url_lit).unwrap()) + )) + } + if let Some(ref license) = self.license { + builder_tokens.append(quote! ( + .license(#license) + )) + } + // done building + builder_tokens.append(quote!( .done(); )) + } +} + impl InkProjectContract { /// Constructs a new InkProjectContractBuilder. pub fn build() -> InkProjectContractBuilder< @@ -214,6 +327,20 @@ pub enum License { Link(Url), } +impl ToTokens for License { + fn to_tokens(&self, tokens: &mut TokenStream) { + match self { + Self::SpdxId(spx_id) => quote! ( ::ink_metadata::License::SpxId(#spx_id) ), + Self::Link(url) => { + let url_lit = url.to_string(); + quote! ( + ::ink_metadata::License::Link(::ink_metadata::Url::parse(#url_lit).unwrap()) + ) + }, + }.to_tokens(tokens) + } +} + /// Additional user defined metadata, can be any valid json. #[derive(Debug, Serialize)] pub struct InkProjectUser { From 725b2cdbdf2f3e0d16703fb9006858206ae98817 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 11:11:12 +0100 Subject: [PATCH 23/39] User and Version --- metadata/src/extension.rs | 60 +++++++++++++++++++++++++++++++++++---- metadata/src/lib.rs | 2 +- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index a96daaaa68a..32fac140292 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -20,9 +20,9 @@ use core::{ Result as DisplayResult, }, marker::PhantomData, + str::FromStr, }; use proc_macro2::TokenStream; -use semver::Version; use serde::{ Serialize, Serializer, @@ -46,7 +46,10 @@ pub struct InkProjectExtension { impl ToTokens for InkProjectExtension { fn to_tokens(&self, tokens: &mut TokenStream) { let source = &self.source; - let user = self.user.map_or(quote!(None), ToTokens::to_token_stream); + let user = match self.user { + Some(ref user) => quote! ( Some(#user) ), + None => quote! ( None ), + }; let contract = &self.contract; quote! ( ::ink_metadata::InkProjectExtension::new(#source, #contract, #user) @@ -79,7 +82,7 @@ pub struct InkProjectSource { impl ToTokens for InkProjectSource { fn to_tokens(&self, tokens: &mut TokenStream) { - let hash = &self.hash; + let hash = format!("{:?}", &self.hash); let language = &self.language; let compiler = &self.compiler; quote! ( @@ -113,7 +116,7 @@ pub struct SourceLanguage { impl ToTokens for SourceLanguage { fn to_tokens(&self, tokens: &mut TokenStream) { let language = &self.language; - let version = &self.version; + let version = self.version.to_string(); quote! ( ::ink_metadata::SourceLanguage::new(#language, #version) ).to_tokens(tokens); @@ -136,6 +139,39 @@ impl Serialize for SourceLanguage { } } +/// Wraps [`semver::Version`] for implementing ToTokens +#[derive(Debug, Serialize)] +pub struct Version(semver::Version); + +impl ToTokens for Version { + fn to_tokens(&self, tokens: &mut TokenStream) { + let version_lit = self.0.to_string(); + quote! ( + ::ink_metadata::Version::from_str(#version_lit).unwrap() + ).to_tokens(tokens) + } +} + +impl Display for Version { + fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { + write!(f, "{}", self.0) + } +} + +impl From for Version { + fn from(version: semver::Version) -> Self { + Version(version) + } +} + +impl FromStr for Version { + type Err = semver::SemVerError; + + fn from_str(s: &str) -> Result { + semver::Version::parse(s).map(Into::into) + } +} + /// The language in which the smart contract is written. #[derive(Debug)] pub enum Language { @@ -179,7 +215,7 @@ impl ToTokens for SourceCompiler { let compiler = &self.compiler; let version = &self.version; quote! ( - ::ink_metadata::SourceCompiler::new(#language, #version) + ::ink_metadata::SourceCompiler::new(#compiler, #version) ).to_tokens(tokens); } } @@ -348,11 +384,25 @@ pub struct InkProjectUser { json: serde_json::Map, } +impl ToTokens for InkProjectUser { + fn to_tokens(&self, tokens: &mut TokenStream) { + let json = serde_json::to_string(&self.json) + .expect("json should be valid json"); + quote! ( + ::ink_metadata::InkProjectUser::from_str(#json).unwrap() + ).to_tokens(tokens) + } +} + impl InkProjectUser { /// Constructs a new InkProjectUser pub fn new(json: Map) -> Self { InkProjectUser { json } } + + pub fn from_str(json: &str) -> serde_json::Result { + serde_json::from_str(json.as_ref()) + } } /// Type state for builders to tell that some mandatory state has not yet been set diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 3750156f4a3..37fc3283757 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -26,7 +26,6 @@ mod specs; mod utils; pub use url::Url; -pub use semver::Version; pub use self::{ extension::{ @@ -39,6 +38,7 @@ pub use self::{ License, SourceCompiler, SourceLanguage, + Version, }, specs::{ ConstructorSpec, From 8ccdfa2dd52a289397f64617e616c4c48ed29f00 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 11:22:28 +0100 Subject: [PATCH 24/39] Fix up builder ToTokens and other errs/warns --- metadata/src/extension.rs | 53 +++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 32fac140292..515f435d3c0 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -32,7 +32,7 @@ use serde_json::{ Value, }; use url::Url; -use quote::{quote, ToTokens, TokenStreamExt}; +use quote::{quote, ToTokens}; /// Additional metadata supplied externally, e.g. by `cargo-contract`. #[derive(Debug, Serialize)] @@ -143,6 +143,12 @@ impl Serialize for SourceLanguage { #[derive(Debug, Serialize)] pub struct Version(semver::Version); +impl Default for Version { + fn default() -> Self { + Version(semver::Version::new(0, 0, 0)) + } +} + impl ToTokens for Version { fn to_tokens(&self, tokens: &mut TokenStream) { let version_lit = self.0.to_string(); @@ -258,7 +264,7 @@ impl Display for Compiler { match self { Self::RustC => write!(f, "rustc"), Self::Solang => write!(f, "solang"), - Self::Other(other) => write!(f, "other"), + Self::Other(other) => write!(f, "{}", other), } } } @@ -288,46 +294,45 @@ impl ToTokens for InkProjectContract { let authors = &self.authors; // initialise builder with required fields - let mut builder_tokens = - quote! ( - ::ink_metadata::InkProjectContract::build() - .name(#name) - .version(::ink_metadata::Version::parse(#version).unwrap()) - .authors(vec![ - #( #authors, )* - ]) - ); + quote! ( + ::ink_metadata::InkProjectContract::build() + .name(#name) + .version(::ink_metadata::Version::parse(#version).unwrap()) + .authors(vec![ + #( #authors, )* + ]) + ).to_tokens(tokens); // append optional fields if present if let Some(ref description) = self.description { - builder_tokens.append(quote!( + quote!( .description(#description) - )) + ).to_tokens(tokens) } if let Some(ref documentation) = self.documentation { let url_lit = documentation.to_string(); - builder_tokens.append(quote!( + quote!( .documentation(::ink_metadata::Url::parse(#url_lit).unwrap()) - )) + ).to_tokens(tokens) } if let Some(ref repository) = self.repository { let url_lit = repository.to_string(); - builder_tokens.append(quote!( + quote!( .repository(::ink_metadata::Url::parse(#url_lit).unwrap()) - )) + ).to_tokens(tokens) } if let Some(ref homepage) = self.homepage { let url_lit = homepage.to_string(); - builder_tokens.append(quote!( + quote!( .homepage(::ink_metadata::Url::parse(#url_lit).unwrap()) - )) + ).to_tokens(tokens) } if let Some(ref license) = self.license { - builder_tokens.append(quote! ( + quote! ( .license(#license) - )) + ).to_tokens(tokens) } // done building - builder_tokens.append(quote!( .done(); )) + quote!( .done(); ).to_tokens(tokens) } } @@ -341,7 +346,7 @@ impl InkProjectContract { InkProjectContractBuilder { contract: Self { name: Default::default(), - version: Version::new(0, 0, 0), + version: Default::default(), authors: vec![], description: None, documentation: None, @@ -401,7 +406,7 @@ impl InkProjectUser { } pub fn from_str(json: &str) -> serde_json::Result { - serde_json::from_str(json.as_ref()) + serde_json::from_str(json.as_ref()).map(Self::new) } } From 134bb7bf022d1248b212dc08d9a21495cd08ac1f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 11:23:23 +0100 Subject: [PATCH 25/39] Fmt --- metadata/src/extension.rs | 66 ++++++++++++++++++++++++--------------- metadata/src/specs.rs | 4 +-- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 515f435d3c0..0838e195ffe 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -23,6 +23,10 @@ use core::{ str::FromStr, }; use proc_macro2::TokenStream; +use quote::{ + quote, + ToTokens, +}; use serde::{ Serialize, Serializer, @@ -32,7 +36,6 @@ use serde_json::{ Value, }; use url::Url; -use quote::{quote, ToTokens}; /// Additional metadata supplied externally, e.g. by `cargo-contract`. #[derive(Debug, Serialize)] @@ -48,12 +51,13 @@ impl ToTokens for InkProjectExtension { let source = &self.source; let user = match self.user { Some(ref user) => quote! ( Some(#user) ), - None => quote! ( None ), + None => quote!(None), }; let contract = &self.contract; quote! ( ::ink_metadata::InkProjectExtension::new(#source, #contract, #user) - ).to_tokens(tokens); + ) + .to_tokens(tokens); } } @@ -87,7 +91,8 @@ impl ToTokens for InkProjectSource { let compiler = &self.compiler; quote! ( ::ink_metadata::InkProjectSource::new(#hash, #language, #compiler) - ).to_tokens(tokens); + ) + .to_tokens(tokens); } } @@ -119,7 +124,8 @@ impl ToTokens for SourceLanguage { let version = self.version.to_string(); quote! ( ::ink_metadata::SourceLanguage::new(#language, #version) - ).to_tokens(tokens); + ) + .to_tokens(tokens); } } @@ -154,7 +160,8 @@ impl ToTokens for Version { let version_lit = self.0.to_string(); quote! ( ::ink_metadata::Version::from_str(#version_lit).unwrap() - ).to_tokens(tokens) + ) + .to_tokens(tokens) } } @@ -190,11 +197,12 @@ pub enum Language { impl ToTokens for Language { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - Self::Ink => quote! ( ::ink_metadata::Language::Ink ), - Self::Solidity => quote! ( ::ink_metadata::Language::Solidity ), - Self::AssemblyScript => quote! ( ::ink_metadata::Language::AssemblyScript ), + Self::Ink => quote!(::ink_metadata::Language::Ink), + Self::Solidity => quote!(::ink_metadata::Language::Solidity), + Self::AssemblyScript => quote!(::ink_metadata::Language::AssemblyScript), Self::Other(other) => quote! ( ::ink_metadata::Language::Other(#other) ), - }.to_tokens(tokens) + } + .to_tokens(tokens) } } @@ -222,14 +230,15 @@ impl ToTokens for SourceCompiler { let version = &self.version; quote! ( ::ink_metadata::SourceCompiler::new(#compiler, #version) - ).to_tokens(tokens); + ) + .to_tokens(tokens); } } impl Serialize for SourceCompiler { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { serializer.serialize_str(&format!("{} {}", self.compiler, self.version)) } @@ -252,10 +261,11 @@ pub enum Compiler { impl ToTokens for Compiler { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - Self::RustC => quote! ( ::ink_metadata::Compiler::Solidity ), - Self::Solang => quote! ( ::ink_metadata::Compiler::AssemblyScript ), + Self::RustC => quote!(::ink_metadata::Compiler::Solidity), + Self::Solang => quote!(::ink_metadata::Compiler::AssemblyScript), Self::Other(other) => quote! ( ::ink_metadata::Compiler::Other(#other) ), - }.to_tokens(tokens) + } + .to_tokens(tokens) } } @@ -301,35 +311,41 @@ impl ToTokens for InkProjectContract { .authors(vec![ #( #authors, )* ]) - ).to_tokens(tokens); + ) + .to_tokens(tokens); // append optional fields if present if let Some(ref description) = self.description { quote!( .description(#description) - ).to_tokens(tokens) + ) + .to_tokens(tokens) } if let Some(ref documentation) = self.documentation { let url_lit = documentation.to_string(); quote!( .documentation(::ink_metadata::Url::parse(#url_lit).unwrap()) - ).to_tokens(tokens) + ) + .to_tokens(tokens) } if let Some(ref repository) = self.repository { let url_lit = repository.to_string(); quote!( .repository(::ink_metadata::Url::parse(#url_lit).unwrap()) - ).to_tokens(tokens) + ) + .to_tokens(tokens) } if let Some(ref homepage) = self.homepage { let url_lit = homepage.to_string(); quote!( .homepage(::ink_metadata::Url::parse(#url_lit).unwrap()) - ).to_tokens(tokens) + ) + .to_tokens(tokens) } if let Some(ref license) = self.license { quote! ( .license(#license) - ).to_tokens(tokens) + ) + .to_tokens(tokens) } // done building quote!( .done(); ).to_tokens(tokens) @@ -391,11 +407,11 @@ pub struct InkProjectUser { impl ToTokens for InkProjectUser { fn to_tokens(&self, tokens: &mut TokenStream) { - let json = serde_json::to_string(&self.json) - .expect("json should be valid json"); + let json = serde_json::to_string(&self.json).expect("json should be valid json"); quote! ( ::ink_metadata::InkProjectUser::from_str(#json).unwrap() - ).to_tokens(tokens) + ) + .to_tokens(tokens) } } diff --git a/metadata/src/specs.rs b/metadata/src/specs.rs index 42ca28f6774..3b0c49037dd 100644 --- a/metadata/src/specs.rs +++ b/metadata/src/specs.rs @@ -227,9 +227,7 @@ pub struct ConstructorSpecBuilder { impl ConstructorSpec { /// Creates a new constructor spec builder. - pub fn new( - name: &'static str, - ) -> ConstructorSpecBuilder> { + pub fn new(name: &'static str) -> ConstructorSpecBuilder> { ConstructorSpecBuilder { spec: Self { name, From 41438d15cd18033c373fdf65ac63c585173d0bad Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 11:42:46 +0100 Subject: [PATCH 26/39] Url wrapper --- metadata/src/extension.rs | 62 ++++++++++++++++++++++++--------------- metadata/src/lib.rs | 3 +- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 0838e195ffe..4075150ac55 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -35,7 +35,6 @@ use serde_json::{ Map, Value, }; -use url::Url; /// Additional metadata supplied externally, e.g. by `cargo-contract`. #[derive(Debug, Serialize)] @@ -185,6 +184,39 @@ impl FromStr for Version { } } +/// Wraps [`url::Url`] for implementing ToTokens +#[derive(Debug, Serialize)] +pub struct Url(url::Url); + +impl ToTokens for Url { + fn to_tokens(&self, tokens: &mut TokenStream) { + let url_lit = self.0.to_string(); + quote! ( + ::ink_metadata::Url::from_str(#url_lit).unwrap() + ).to_tokens(tokens) + } +} + +impl Display for Url { + fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { + write!(f, "{}", self.0) + } +} + +impl From for Url { + fn from(url: url::Url) -> Self { + Url(url) + } +} + +impl FromStr for Url { + type Err = url::ParseError; + + fn from_str(s: &str) -> Result { + url::Url::parse(s).map(Into::into) + } +} + /// The language in which the smart contract is written. #[derive(Debug)] pub enum Language { @@ -315,37 +347,19 @@ impl ToTokens for InkProjectContract { .to_tokens(tokens); // append optional fields if present if let Some(ref description) = self.description { - quote!( - .description(#description) - ) - .to_tokens(tokens) + quote! ( .description(#description)).to_tokens(tokens) } if let Some(ref documentation) = self.documentation { - let url_lit = documentation.to_string(); - quote!( - .documentation(::ink_metadata::Url::parse(#url_lit).unwrap()) - ) - .to_tokens(tokens) + quote! ( .documentation(#documentation) ).to_tokens(tokens) } if let Some(ref repository) = self.repository { - let url_lit = repository.to_string(); - quote!( - .repository(::ink_metadata::Url::parse(#url_lit).unwrap()) - ) - .to_tokens(tokens) + quote! ( .repository(#repository) ).to_tokens(tokens) } if let Some(ref homepage) = self.homepage { - let url_lit = homepage.to_string(); - quote!( - .homepage(::ink_metadata::Url::parse(#url_lit).unwrap()) - ) - .to_tokens(tokens) + quote! ( .homepage(#homepage) ).to_tokens(tokens) } if let Some(ref license) = self.license { - quote! ( - .license(#license) - ) - .to_tokens(tokens) + quote! ( .license(#license) ).to_tokens(tokens) } // done building quote!( .done(); ).to_tokens(tokens) diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 37fc3283757..5776fd181f9 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -25,8 +25,6 @@ pub mod layout2; mod specs; mod utils; -pub use url::Url; - pub use self::{ extension::{ Compiler, @@ -39,6 +37,7 @@ pub use self::{ SourceCompiler, SourceLanguage, Version, + Url, }, specs::{ ConstructorSpec, From c4d301531ca34df3282a4b93e70a29abb07fe069 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 12:03:11 +0100 Subject: [PATCH 27/39] Comment and Version/Url intos --- metadata/src/extension.rs | 40 +++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 4075150ac55..a9a780e7aef 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -37,6 +37,14 @@ use serde_json::{ }; /// Additional metadata supplied externally, e.g. by `cargo-contract`. +/// +/// # Usage +/// +/// An instance can be constructed, and from this the code to construct an equivalent instance can +/// be generated using [`quote::ToTokens`]. +/// +/// This can be used by a build tool such as `cargo-contract` for marshalling extra metadata +/// into this contract's metadata generation routine. #[derive(Debug, Serialize)] pub struct InkProjectExtension { source: InkProjectSource, @@ -510,13 +518,16 @@ impl InkProjectContractBuilder, V, A> { impl InkProjectContractBuilder, A> { /// Set the contract version (required) - pub fn version( + pub fn version( self, - version: Version, - ) -> InkProjectContractBuilder { + version: V, + ) -> InkProjectContractBuilder + where + V: Into + { InkProjectContractBuilder { contract: InkProjectContract { - version, + version: version.into(), ..self.contract }, marker: PhantomData, @@ -555,20 +566,29 @@ impl InkProjectContractBuilder { } /// Set the contract documentation url (optional) - pub fn documentation(mut self, documentation: Url) -> Self { - self.contract.documentation = Some(documentation); + pub fn documentation(mut self, documentation: U) -> Self + where + U: Into + { + self.contract.documentation = Some(documentation.into()); self } /// Set the contract documentation url (optional) - pub fn repository(mut self, repository: Url) -> Self { - self.contract.repository = Some(repository); + pub fn repository(mut self, repository: U) -> Self + where + U: Into + { + self.contract.repository = Some(repository.into()); self } /// Set the contract homepage url (optional) - pub fn homepage(mut self, homepage: Url) -> Self { - self.contract.homepage = Some(homepage); + pub fn homepage(mut self, homepage: U) -> Self + where + U: Into + { + self.contract.homepage = Some(homepage.into()); self } From f2d28b83d2b94b80d1ebb46012760d7c5dc633b8 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 12:08:29 +0100 Subject: [PATCH 28/39] Fmt --- metadata/src/extension.rs | 16 +++++++--------- metadata/src/lib.rs | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index a9a780e7aef..21e50157041 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -201,7 +201,8 @@ impl ToTokens for Url { let url_lit = self.0.to_string(); quote! ( ::ink_metadata::Url::from_str(#url_lit).unwrap() - ).to_tokens(tokens) + ) + .to_tokens(tokens) } } @@ -518,12 +519,9 @@ impl InkProjectContractBuilder, V, A> { impl InkProjectContractBuilder, A> { /// Set the contract version (required) - pub fn version( - self, - version: V, - ) -> InkProjectContractBuilder + pub fn version(self, version: V) -> InkProjectContractBuilder where - V: Into + V: Into, { InkProjectContractBuilder { contract: InkProjectContract { @@ -568,7 +566,7 @@ impl InkProjectContractBuilder { /// Set the contract documentation url (optional) pub fn documentation(mut self, documentation: U) -> Self where - U: Into + U: Into, { self.contract.documentation = Some(documentation.into()); self @@ -577,7 +575,7 @@ impl InkProjectContractBuilder { /// Set the contract documentation url (optional) pub fn repository(mut self, repository: U) -> Self where - U: Into + U: Into, { self.contract.repository = Some(repository.into()); self @@ -586,7 +584,7 @@ impl InkProjectContractBuilder { /// Set the contract homepage url (optional) pub fn homepage(mut self, homepage: U) -> Self where - U: Into + U: Into, { self.contract.homepage = Some(homepage.into()); self diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 5776fd181f9..6d945adca52 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -36,8 +36,8 @@ pub use self::{ License, SourceCompiler, SourceLanguage, - Version, Url, + Version, }, specs::{ ConstructorSpec, From 71b76b6da1963a194e409611ae23364dddb27660 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 12:11:13 +0100 Subject: [PATCH 29/39] Fix U --- metadata/src/extension.rs | 2 +- metadata/src/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/metadata/src/extension.rs b/metadata/src/extension.rs index 21e50157041..7fbfee06060 100644 --- a/metadata/src/extension.rs +++ b/metadata/src/extension.rs @@ -573,7 +573,7 @@ impl InkProjectContractBuilder { } /// Set the contract documentation url (optional) - pub fn repository(mut self, repository: U) -> Self + pub fn repository(mut self, repository: U) -> Self where U: Into, { diff --git a/metadata/src/tests.rs b/metadata/src/tests.rs index 3202413b8ff..28171d8afc1 100644 --- a/metadata/src/tests.rs +++ b/metadata/src/tests.rs @@ -48,7 +48,7 @@ fn spec_constructor_selector_must_serialize_to_hex() { #[test] fn spec_contract_json() { // given - let contract: ContractSpec = ContractSpec::new("incrementer") + let contract: ContractSpec = ContractSpec::new() .constructors(vec![ ConstructorSpec::new("new") .selector([94u8, 189u8, 136u8, 214u8]) From cbc17b4f30b41e8e1d6f6430da43731559588822 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 7 Jul 2020 12:16:10 +0100 Subject: [PATCH 30/39] Promote extension to module dir --- metadata/src/{extension.rs => extension/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename metadata/src/{extension.rs => extension/mod.rs} (100%) diff --git a/metadata/src/extension.rs b/metadata/src/extension/mod.rs similarity index 100% rename from metadata/src/extension.rs rename to metadata/src/extension/mod.rs From 2cf8ee47aea481000f488e0731e711089ac03f21 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 8 Jul 2020 09:21:17 +0100 Subject: [PATCH 31/39] Moved InkProjectExtension to cargo-contract --- lang/macro/src/codegen/metadata.rs | 4 +- metadata/Cargo.toml | 2 - metadata/src/extension/mod.rs | 604 ----------------------------- metadata/src/lib.rs | 62 +-- 4 files changed, 22 insertions(+), 650 deletions(-) delete mode 100644 metadata/src/extension/mod.rs diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 25738a3ef3d..bde44501397 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -42,14 +42,14 @@ impl GenerateCode for GenerateMetadata<'_> { #[cfg(not(feature = "ink-as-dependency"))] const _: () = { #[no_mangle] - pub fn __ink_generate_metadata(extension: ::ink_metadata::InkProjectExtension) -> ::ink_metadata::InkProject { + pub fn __ink_generate_metadata() -> ::ink_metadata::InkProject { let contract: ::ink_metadata::ContractSpec = { #contract }; let layout: ::ink_metadata::layout2::StorageLayout = { #layout }; - ::ink_metadata::InkProject::new(extension, layout, contract) + ::ink_metadata::InkProject::new(layout, contract) } }; } diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index b0be9a42e7b..d8ef9db69d3 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -21,11 +21,9 @@ ink_primitives = { version = "2.1.0", path = "../primitives/", default-features serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } serde_json = "1.0" derive_more = { version = "0.99", default-features = false, features = ["from"] } -proc-macro2 = "1.0" scale-info = { version = "0.3", default-features = false, features = ["derive"] } semver = { version = "0.10.0", features = ["serde"] } url = { version = "2.1.1", features = ["serde"] } -quote = "1.0" [dev-dependencies] assert-json-diff = "1.0.1" diff --git a/metadata/src/extension/mod.rs b/metadata/src/extension/mod.rs deleted file mode 100644 index 7fbfee06060..00000000000 --- a/metadata/src/extension/mod.rs +++ /dev/null @@ -1,604 +0,0 @@ -// Copyright 2018-2019 Parity Technologies (UK) Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use crate::utils::serialize_as_byte_str; -use core::{ - fmt::{ - Display, - Formatter, - Result as DisplayResult, - }, - marker::PhantomData, - str::FromStr, -}; -use proc_macro2::TokenStream; -use quote::{ - quote, - ToTokens, -}; -use serde::{ - Serialize, - Serializer, -}; -use serde_json::{ - Map, - Value, -}; - -/// Additional metadata supplied externally, e.g. by `cargo-contract`. -/// -/// # Usage -/// -/// An instance can be constructed, and from this the code to construct an equivalent instance can -/// be generated using [`quote::ToTokens`]. -/// -/// This can be used by a build tool such as `cargo-contract` for marshalling extra metadata -/// into this contract's metadata generation routine. -#[derive(Debug, Serialize)] -pub struct InkProjectExtension { - source: InkProjectSource, - contract: InkProjectContract, - #[serde(skip_serializing_if = "Option::is_none")] - user: Option, -} - -impl ToTokens for InkProjectExtension { - fn to_tokens(&self, tokens: &mut TokenStream) { - let source = &self.source; - let user = match self.user { - Some(ref user) => quote! ( Some(#user) ), - None => quote!(None), - }; - let contract = &self.contract; - quote! ( - ::ink_metadata::InkProjectExtension::new(#source, #contract, #user) - ) - .to_tokens(tokens); - } -} - -impl InkProjectExtension { - /// Constructs a new InkProjectExtension. - pub fn new( - source: InkProjectSource, - contract: InkProjectContract, - user: Option, - ) -> Self { - InkProjectExtension { - source, - contract, - user, - } - } -} - -#[derive(Debug, Serialize)] -pub struct InkProjectSource { - #[serde(serialize_with = "serialize_as_byte_str")] - hash: [u8; 32], - language: SourceLanguage, - compiler: SourceCompiler, -} - -impl ToTokens for InkProjectSource { - fn to_tokens(&self, tokens: &mut TokenStream) { - let hash = format!("{:?}", &self.hash); - let language = &self.language; - let compiler = &self.compiler; - quote! ( - ::ink_metadata::InkProjectSource::new(#hash, #language, #compiler) - ) - .to_tokens(tokens); - } -} - -impl InkProjectSource { - /// Constructs a new InkProjectSource. - pub fn new( - hash: [u8; 32], - language: SourceLanguage, - compiler: SourceCompiler, - ) -> Self { - InkProjectSource { - hash, - language, - compiler, - } - } -} - -/// The language and version in which a smart contract is written. -#[derive(Debug)] -pub struct SourceLanguage { - language: Language, - version: Version, -} - -impl ToTokens for SourceLanguage { - fn to_tokens(&self, tokens: &mut TokenStream) { - let language = &self.language; - let version = self.version.to_string(); - quote! ( - ::ink_metadata::SourceLanguage::new(#language, #version) - ) - .to_tokens(tokens); - } -} - -impl SourceLanguage { - /// Constructs a new SourceLanguage. - pub fn new(language: Language, version: Version) -> Self { - SourceLanguage { language, version } - } -} - -impl Serialize for SourceLanguage { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&format!("{} {}", self.language, self.version)) - } -} - -/// Wraps [`semver::Version`] for implementing ToTokens -#[derive(Debug, Serialize)] -pub struct Version(semver::Version); - -impl Default for Version { - fn default() -> Self { - Version(semver::Version::new(0, 0, 0)) - } -} - -impl ToTokens for Version { - fn to_tokens(&self, tokens: &mut TokenStream) { - let version_lit = self.0.to_string(); - quote! ( - ::ink_metadata::Version::from_str(#version_lit).unwrap() - ) - .to_tokens(tokens) - } -} - -impl Display for Version { - fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { - write!(f, "{}", self.0) - } -} - -impl From for Version { - fn from(version: semver::Version) -> Self { - Version(version) - } -} - -impl FromStr for Version { - type Err = semver::SemVerError; - - fn from_str(s: &str) -> Result { - semver::Version::parse(s).map(Into::into) - } -} - -/// Wraps [`url::Url`] for implementing ToTokens -#[derive(Debug, Serialize)] -pub struct Url(url::Url); - -impl ToTokens for Url { - fn to_tokens(&self, tokens: &mut TokenStream) { - let url_lit = self.0.to_string(); - quote! ( - ::ink_metadata::Url::from_str(#url_lit).unwrap() - ) - .to_tokens(tokens) - } -} - -impl Display for Url { - fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { - write!(f, "{}", self.0) - } -} - -impl From for Url { - fn from(url: url::Url) -> Self { - Url(url) - } -} - -impl FromStr for Url { - type Err = url::ParseError; - - fn from_str(s: &str) -> Result { - url::Url::parse(s).map(Into::into) - } -} - -/// The language in which the smart contract is written. -#[derive(Debug)] -pub enum Language { - Ink, - Solidity, - AssemblyScript, - Other(&'static str), -} - -impl ToTokens for Language { - fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - Self::Ink => quote!(::ink_metadata::Language::Ink), - Self::Solidity => quote!(::ink_metadata::Language::Solidity), - Self::AssemblyScript => quote!(::ink_metadata::Language::AssemblyScript), - Self::Other(other) => quote! ( ::ink_metadata::Language::Other(#other) ), - } - .to_tokens(tokens) - } -} - -impl Display for Language { - fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { - match self { - Self::Ink => write!(f, "ink!"), - Self::Solidity => write!(f, "Solidity"), - Self::AssemblyScript => write!(f, "AssemblyScript"), - Self::Other(lang) => write!(f, "{}", lang), - } - } -} - -/// A compiler used to compile a smart contract. -#[derive(Debug)] -pub struct SourceCompiler { - compiler: Compiler, - version: Version, -} - -impl ToTokens for SourceCompiler { - fn to_tokens(&self, tokens: &mut TokenStream) { - let compiler = &self.compiler; - let version = &self.version; - quote! ( - ::ink_metadata::SourceCompiler::new(#compiler, #version) - ) - .to_tokens(tokens); - } -} - -impl Serialize for SourceCompiler { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&format!("{} {}", self.compiler, self.version)) - } -} - -impl SourceCompiler { - pub fn new(compiler: Compiler, version: Version) -> Self { - SourceCompiler { compiler, version } - } -} - -/// Compilers used to compile a smart contract. -#[derive(Debug, Serialize)] -pub enum Compiler { - RustC, - Solang, - Other(&'static str), -} - -impl ToTokens for Compiler { - fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - Self::RustC => quote!(::ink_metadata::Compiler::Solidity), - Self::Solang => quote!(::ink_metadata::Compiler::AssemblyScript), - Self::Other(other) => quote! ( ::ink_metadata::Compiler::Other(#other) ), - } - .to_tokens(tokens) - } -} - -impl Display for Compiler { - fn fmt(&self, f: &mut Formatter<'_>) -> DisplayResult { - match self { - Self::RustC => write!(f, "rustc"), - Self::Solang => write!(f, "solang"), - Self::Other(other) => write!(f, "{}", other), - } - } -} - -/// Metadata about a smart contract. -#[derive(Debug, Serialize)] -pub struct InkProjectContract { - name: String, - version: Version, - authors: Vec, - #[serde(skip_serializing_if = "Option::is_none")] - description: Option, - #[serde(skip_serializing_if = "Option::is_none")] - documentation: Option, - #[serde(skip_serializing_if = "Option::is_none")] - repository: Option, - #[serde(skip_serializing_if = "Option::is_none")] - homepage: Option, - #[serde(skip_serializing_if = "Option::is_none")] - license: Option, -} - -impl ToTokens for InkProjectContract { - fn to_tokens(&self, tokens: &mut TokenStream) { - let name = &self.name; - let version = self.version.to_string(); - let authors = &self.authors; - - // initialise builder with required fields - quote! ( - ::ink_metadata::InkProjectContract::build() - .name(#name) - .version(::ink_metadata::Version::parse(#version).unwrap()) - .authors(vec![ - #( #authors, )* - ]) - ) - .to_tokens(tokens); - // append optional fields if present - if let Some(ref description) = self.description { - quote! ( .description(#description)).to_tokens(tokens) - } - if let Some(ref documentation) = self.documentation { - quote! ( .documentation(#documentation) ).to_tokens(tokens) - } - if let Some(ref repository) = self.repository { - quote! ( .repository(#repository) ).to_tokens(tokens) - } - if let Some(ref homepage) = self.homepage { - quote! ( .homepage(#homepage) ).to_tokens(tokens) - } - if let Some(ref license) = self.license { - quote! ( .license(#license) ).to_tokens(tokens) - } - // done building - quote!( .done(); ).to_tokens(tokens) - } -} - -impl InkProjectContract { - /// Constructs a new InkProjectContractBuilder. - pub fn build() -> InkProjectContractBuilder< - Missing, - Missing, - Missing, - > { - InkProjectContractBuilder { - contract: Self { - name: Default::default(), - version: Default::default(), - authors: vec![], - description: None, - documentation: None, - repository: None, - homepage: None, - license: None, - }, - marker: Default::default(), - } - } -} - -/// The license of a smart contract -#[derive(Debug, Serialize)] -pub enum License { - /// An [SPDX identifier](https://spdx.org/licenses/) - SpdxId(String), - /// A URL to a custom license - Link(Url), -} - -impl ToTokens for License { - fn to_tokens(&self, tokens: &mut TokenStream) { - match self { - Self::SpdxId(spx_id) => quote! ( ::ink_metadata::License::SpxId(#spx_id) ), - Self::Link(url) => { - let url_lit = url.to_string(); - quote! ( - ::ink_metadata::License::Link(::ink_metadata::Url::parse(#url_lit).unwrap()) - ) - }, - }.to_tokens(tokens) - } -} - -/// Additional user defined metadata, can be any valid json. -#[derive(Debug, Serialize)] -pub struct InkProjectUser { - #[serde(flatten)] - json: serde_json::Map, -} - -impl ToTokens for InkProjectUser { - fn to_tokens(&self, tokens: &mut TokenStream) { - let json = serde_json::to_string(&self.json).expect("json should be valid json"); - quote! ( - ::ink_metadata::InkProjectUser::from_str(#json).unwrap() - ) - .to_tokens(tokens) - } -} - -impl InkProjectUser { - /// Constructs a new InkProjectUser - pub fn new(json: Map) -> Self { - InkProjectUser { json } - } - - pub fn from_str(json: &str) -> serde_json::Result { - serde_json::from_str(json.as_ref()).map(Self::new) - } -} - -/// Type state for builders to tell that some mandatory state has not yet been set -/// yet or to fail upon setting the same state multiple times. -pub struct Missing(PhantomData S>); - -mod state { - //! Type states that tell what state of the project metadata has not - //! yet been set properly for a valid construction. - - /// Type state for the name of the project. - pub struct Name; - - /// Type state for the version of the project. - pub struct Version; - - /// Type state for the authors of the project. - pub struct Authors; -} - -/// Build an [`InkProjectContract`], ensuring required fields are supplied -/// -/// # Example -/// -/// ``` -/// # use crate::ink_metadata::InkProjectContract; -/// # use semver::Version; -/// # use url::Url; -/// // contract metadata with the minimum set of required fields -/// let metadata1: InkProjectContract = -/// InkProjectContract::build() -/// .name("example") -/// .version(Version::new(0, 1, 0)) -/// .authors(vec!["author@example.com"]) -/// .done(); -/// -/// // contract metadata with optional fields -/// let metadata2: InkProjectContract = -/// InkProjectContract::build() -/// .name("example") -/// .version(Version::new(0, 1, 0)) -/// .authors(vec!["author@example.com"]) -/// .description("description") -/// .documentation(Url::parse("http://example.com").unwrap()) -/// .repository(Url::parse("http://example.com").unwrap()) -/// .homepage(Url::parse("http://example.com").unwrap()) -/// .done(); -/// ``` -#[allow(clippy::type_complexity)] -pub struct InkProjectContractBuilder { - contract: InkProjectContract, - marker: PhantomData (Name, Version, Authors)>, -} - -impl InkProjectContractBuilder, V, A> { - /// Set the contract name (required) - pub fn name(self, name: S) -> InkProjectContractBuilder - where - S: AsRef, - { - InkProjectContractBuilder { - contract: InkProjectContract { - name: name.as_ref().to_owned(), - ..self.contract - }, - marker: PhantomData, - } - } -} - -impl InkProjectContractBuilder, A> { - /// Set the contract version (required) - pub fn version(self, version: V) -> InkProjectContractBuilder - where - V: Into, - { - InkProjectContractBuilder { - contract: InkProjectContract { - version: version.into(), - ..self.contract - }, - marker: PhantomData, - } - } -} - -impl InkProjectContractBuilder> { - /// Set the contract authors (required) - pub fn authors( - self, - authors: I, - ) -> InkProjectContractBuilder - where - I: IntoIterator, - S: AsRef, - { - InkProjectContractBuilder { - contract: InkProjectContract { - authors: authors.into_iter().map(|s| s.as_ref().into()).collect(), - ..self.contract - }, - marker: PhantomData, - } - } -} - -impl InkProjectContractBuilder { - /// Set the contract description (optional) - pub fn description(mut self, description: S) -> Self - where - S: AsRef, - { - self.contract.description = Some(description.as_ref().to_owned()); - self - } - - /// Set the contract documentation url (optional) - pub fn documentation(mut self, documentation: U) -> Self - where - U: Into, - { - self.contract.documentation = Some(documentation.into()); - self - } - - /// Set the contract documentation url (optional) - pub fn repository(mut self, repository: U) -> Self - where - U: Into, - { - self.contract.repository = Some(repository.into()); - self - } - - /// Set the contract homepage url (optional) - pub fn homepage(mut self, homepage: U) -> Self - where - U: Into, - { - self.contract.homepage = Some(homepage.into()); - self - } - - /// Set the contract license (optional) - pub fn license(mut self, license: License) -> Self { - self.contract.license = Some(license); - self - } -} - -impl InkProjectContractBuilder { - pub fn done(self) -> InkProjectContract { - self.contract - } -} diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 6d945adca52..c67f6f51853 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -20,42 +20,26 @@ extern crate alloc; #[cfg(test)] mod tests; -mod extension; pub mod layout2; mod specs; mod utils; -pub use self::{ - extension::{ - Compiler, - InkProjectContract, - InkProjectExtension, - InkProjectSource, - InkProjectUser, - Language, - License, - SourceCompiler, - SourceLanguage, - Url, - Version, - }, - specs::{ - ConstructorSpec, - ConstructorSpecBuilder, - ContractSpec, - ContractSpecBuilder, - DisplayName, - EventParamSpec, - EventParamSpecBuilder, - EventSpec, - EventSpecBuilder, - MessageParamSpec, - MessageParamSpecBuilder, - MessageSpec, - MessageSpecBuilder, - ReturnTypeSpec, - TypeSpec, - }, +pub use self::specs::{ + ConstructorSpec, + ConstructorSpecBuilder, + ContractSpec, + ContractSpecBuilder, + DisplayName, + EventParamSpec, + EventParamSpecBuilder, + EventSpec, + EventSpecBuilder, + MessageParamSpec, + MessageParamSpecBuilder, + MessageSpec, + MessageSpecBuilder, + ReturnTypeSpec, + TypeSpec, }; #[cfg(feature = "derive")] @@ -66,34 +50,28 @@ use scale_info::{ }; use serde::Serialize; -const METADATA_VERSION: &str = "0.1.0"; - -/// An entire ink! project for ABI file generation purposes. +/// An entire ink! project for metadata file generation purposes. #[derive(Debug, Serialize)] pub struct InkProject { - metadata_version: semver::Version, #[serde(flatten)] - extension: InkProjectExtension, + registry: Registry, #[serde(rename = "storage")] layout: layout2::StorageLayout, spec: ContractSpec, } impl InkProject { - pub fn new(extension: InkProjectExtension, layout: L, spec: S) -> Self + pub fn new(layout: L, spec: S) -> Self where L: Into, S: Into, { - let metadata_version = semver::Version::parse(METADATA_VERSION) - .expect("METADATA_VERSION is a valid semver string"); let mut registry = Registry::new(); InkProject { - metadata_version, - extension, layout: layout.into().into_compact(&mut registry), spec: spec.into().into_compact(&mut registry), + registry, } } } From f13b888fb759cb4df9803ad0ce3498229bed7dae Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 8 Jul 2020 11:25:24 +0100 Subject: [PATCH 32/39] Fix doc gen --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index acfff9a0d90..633c622b029 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -255,7 +255,7 @@ publish-docs: - git fetch origin gh-pages # Generating Docs - time cargo doc --no-deps --all-features - -p scale-info -p ink_metadata -p ink_metadata_derive -p ink_core -p ink_core_derive + -p scale-info -p ink_metadata -p ink_core -p ink_core_derive -p ink_primitives -p ink_prelude -p ink_lang -p ink_lang_macro # saving README and docs - mv target/doc/ /tmp/ From ad7e5b4c7c514702fca9a598bee37e4337235e7f Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 13 Jul 2020 15:53:01 +0100 Subject: [PATCH 33/39] Fix json tests --- metadata/src/tests.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/metadata/src/tests.rs b/metadata/src/tests.rs index 28171d8afc1..fbcc8b569c9 100644 --- a/metadata/src/tests.rs +++ b/metadata/src/tests.rs @@ -37,7 +37,7 @@ fn spec_constructor_selector_must_serialize_to_hex() { assert_json_eq!( json, json!({ - "name": 1, + "name": "foo", "selector": "0x075bcd15", "args": [], "docs": [] @@ -104,23 +104,23 @@ fn spec_contract_json() { { "args": [ { - "name": 3, + "name": "init_value", "type": { "displayName": [ - 4 + "i32" ], "id": 1 } } ], "docs": [], - "name": 2, + "name": "new", "selector": "0x5ebd88d6" }, { "args": [], "docs": [], - "name": 5, + "name": "default", "selector": "0x0222ff18" } ], @@ -130,10 +130,10 @@ fn spec_contract_json() { { "args": [ { - "name": 7, + "name": "by", "type": { "displayName": [ - 4 + "i32" ], "id": 1 } @@ -141,7 +141,7 @@ fn spec_contract_json() { ], "docs": [], "mutates": true, - "name": 6, + "name": "inc", "returnType": null, "selector": "0xe7d0590f" }, @@ -149,17 +149,16 @@ fn spec_contract_json() { "args": [], "docs": [], "mutates": false, - "name": 8, + "name": "get", "returnType": { "displayName": [ - 4 + "i32" ], "id": 1 }, "selector": "0x25444afe" } ], - "name": 1 }) ) } From 3d3e7f1f94c2c883af0f2bcb1de48c51ac87eddb Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Mon, 13 Jul 2020 15:58:48 +0100 Subject: [PATCH 34/39] Use pretty assertions and fix layout json tests --- metadata/Cargo.toml | 2 +- metadata/src/layout2/tests.rs | 9 +++++---- metadata/src/tests.rs | 6 +++--- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index d8ef9db69d3..a2878d0a22e 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -26,7 +26,7 @@ semver = { version = "0.10.0", features = ["serde"] } url = { version = "2.1.1", features = ["serde"] } [dev-dependencies] -assert-json-diff = "1.0.1" +pretty_assertions = "0.6.1" [features] default = [ diff --git a/metadata/src/layout2/tests.rs b/metadata/src/layout2/tests.rs index de6b4e2fecc..d4604f8974e 100644 --- a/metadata/src/layout2/tests.rs +++ b/metadata/src/layout2/tests.rs @@ -14,6 +14,7 @@ use super::*; use ink_primitives::KeyPtr; +use pretty_assertions::assert_eq; #[test] fn layout_key_works() { @@ -60,7 +61,7 @@ fn named_fields_work() { "ty": 1, } }, - "name": 1, + "name": "a", }, { "layout": { @@ -73,7 +74,7 @@ fn named_fields_work() { "ty": 2, } }, - "name": 2, + "name": "b", } ] } @@ -293,7 +294,7 @@ fn mixed_enum_work() { "ty": 1, } }, - "name": 1, + "name": "a", }, { "layout": { @@ -306,7 +307,7 @@ fn mixed_enum_work() { "ty": 2, } }, - "name": 2, + "name": "b", } ], }, diff --git a/metadata/src/tests.rs b/metadata/src/tests.rs index fbcc8b569c9..aa4b6794901 100644 --- a/metadata/src/tests.rs +++ b/metadata/src/tests.rs @@ -13,7 +13,7 @@ // limitations under the License. use super::*; -use assert_json_diff::assert_json_eq; +use pretty_assertions::assert_eq; use scale_info::{ IntoCompact, Registry, @@ -34,7 +34,7 @@ fn spec_constructor_selector_must_serialize_to_hex() { let json = serde_json::to_value(&cs.into_compact(&mut registry)).unwrap(); // then - assert_json_eq!( + assert_eq!( json, json!({ "name": "foo", @@ -97,7 +97,7 @@ fn spec_contract_json() { let json = serde_json::to_value(&contract.into_compact(&mut registry)).unwrap(); // then - assert_json_eq!( + assert_eq!( json, json!({ "constructors": [ From de7cff15d9dbee0b45b71ed077cbf112243117c4 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 15 Jul 2020 08:58:22 +0100 Subject: [PATCH 35/39] Remove storage name from layout (ink specific) --- lang/macro/src/codegen/metadata.rs | 8 +++----- metadata/src/layout2/mod.rs | 28 ---------------------------- metadata/src/lib.rs | 5 +++-- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index bde44501397..9e83c15777e 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -269,11 +269,9 @@ impl GenerateMetadata<'_> { let contract_ident = &self.contract.storage.ident; let contract_ident_lit = contract_ident.to_string(); quote! { - let layout = - <#contract_ident as ::ink_core::storage2::traits::StorageLayout>::layout( - &mut ::ink_primitives::KeyPtr::from(::ink_primitives::Key::from([0x00; 32])) - ); - ::ink_metadata::layout2::StorageLayout::new(#contract_ident_lit, layout) + <#contract_ident as ::ink_core::storage2::traits::StorageLayout>::layout( + &mut ::ink_primitives::KeyPtr::from(::ink_primitives::Key::from([0x00; 32])) + ) } } } diff --git a/metadata/src/layout2/mod.rs b/metadata/src/layout2/mod.rs index 57e2ceb7b91..b475a2528d4 100644 --- a/metadata/src/layout2/mod.rs +++ b/metadata/src/layout2/mod.rs @@ -31,34 +31,6 @@ use scale_info::{ TypeInfo, }; -/// The name and static storage layout of an ink! smart contract -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, From, serde::Serialize)] -#[serde(bound = "F::TypeId: serde::Serialize")] -pub struct StorageLayout { - /// The name of the storage data structure - name: &'static str, - /// The layout of the storage data structure - layout: Layout, -} - -impl IntoCompact for StorageLayout { - type Output = StorageLayout; - - fn into_compact(self, registry: &mut Registry) -> Self::Output { - StorageLayout { - name: self.name, - layout: self.layout.into_compact(registry), - } - } -} - -impl StorageLayout { - /// Create a new StorageLayout with the name of the storage data structure - pub fn new(name: &'static str, layout: Layout) -> Self { - StorageLayout { name, layout } - } -} - /// Represents the static storage layout of an ink! smart contract. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, From, serde::Serialize)] #[serde(bound = "F::TypeId: serde::Serialize")] diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index c67f6f51853..258c6649015 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -56,14 +56,15 @@ pub struct InkProject { #[serde(flatten)] registry: Registry, #[serde(rename = "storage")] - layout: layout2::StorageLayout, + /// The layout of the storage data structure + layout: layout2::Layout, spec: ContractSpec, } impl InkProject { pub fn new(layout: L, spec: S) -> Self where - L: Into, + L: Into, S: Into, { let mut registry = Registry::new(); From a32fb3a79b222aefea61fda934aec1c1f04659c9 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 15 Jul 2020 09:01:50 +0100 Subject: [PATCH 36/39] StorageLayout -> Layout --- lang/macro/src/codegen/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 9e83c15777e..19f47e90e18 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -46,7 +46,7 @@ impl GenerateCode for GenerateMetadata<'_> { let contract: ::ink_metadata::ContractSpec = { #contract }; - let layout: ::ink_metadata::layout2::StorageLayout = { + let layout: ::ink_metadata::layout2::Layout = { #layout }; ::ink_metadata::InkProject::new(layout, contract) From e6c3587b042ffb09686e90020155962b99ecbff2 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 15 Jul 2020 12:10:42 +0100 Subject: [PATCH 37/39] Remove redundant contract_ident_lit --- lang/macro/src/codegen/metadata.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lang/macro/src/codegen/metadata.rs b/lang/macro/src/codegen/metadata.rs index 19f47e90e18..3621ced43d1 100644 --- a/lang/macro/src/codegen/metadata.rs +++ b/lang/macro/src/codegen/metadata.rs @@ -267,7 +267,6 @@ impl GenerateMetadata<'_> { fn generate_layout(&self) -> TokenStream2 { let contract_ident = &self.contract.storage.ident; - let contract_ident_lit = contract_ident.to_string(); quote! { <#contract_ident as ::ink_core::storage2::traits::StorageLayout>::layout( &mut ::ink_primitives::KeyPtr::from(::ink_primitives::Key::from([0x00; 32])) From 5d6b9b4002d26bc685c4887546900143dbe97980 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 15 Jul 2020 17:21:27 +0100 Subject: [PATCH 38/39] Remove redundant dependencies --- metadata/Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/metadata/Cargo.toml b/metadata/Cargo.toml index a2878d0a22e..ac2fc01c23c 100644 --- a/metadata/Cargo.toml +++ b/metadata/Cargo.toml @@ -19,14 +19,12 @@ ink_prelude = { version = "2.1.0", path = "../prelude/", default-features = fals ink_primitives = { version = "2.1.0", path = "../primitives/", default-features = false } serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } -serde_json = "1.0" derive_more = { version = "0.99", default-features = false, features = ["from"] } scale-info = { version = "0.3", default-features = false, features = ["derive"] } -semver = { version = "0.10.0", features = ["serde"] } -url = { version = "2.1.1", features = ["serde"] } [dev-dependencies] pretty_assertions = "0.6.1" +serde_json = "1.0" [features] default = [ From 06352f73d4cf3ccaccd55972a2aceb0b6cb81cbd Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 15 Jul 2020 17:22:19 +0100 Subject: [PATCH 39/39] Use Self instead of InkProject --- metadata/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 258c6649015..4106a66b70c 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -69,7 +69,7 @@ impl InkProject { { let mut registry = Registry::new(); - InkProject { + Self { layout: layout.into().into_compact(&mut registry), spec: spec.into().into_compact(&mut registry), registry,