-
Notifications
You must be signed in to change notification settings - Fork 430
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable ink_metadata
to be used for metadata generation outside of ink!
#1357
Conversation
ink_metadata
to be used for metadata generation outside of ink!
cfa5ce9
to
98fc658
Compare
crates/metadata/src/specs.rs
Outdated
@@ -397,19 +428,19 @@ pub struct MessageSpec<F: Form = MetaForm> { | |||
/// | |||
/// In case of trait provided messages and constructors the prefix | |||
/// by convention in ink! is the label of the trait. | |||
label: F::String, | |||
pub label: F::String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't forget to remove all these pub
modifiers to require use of builders
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
almost forgot 🐒 thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[must_use]
is set for the new<T>(ty: T)
function, however there is no other means to construct it anyways? There is no builder for ReturnTypeSpec
(probably because there is only one fuild anyways). So I just moved the must_use to the ReturnTypeSpec
itself
Codecov Report
@@ Coverage Diff @@
## master #1357 +/- ##
===========================================
+ Coverage 44.77% 64.16% +19.38%
===========================================
Files 200 200
Lines 6101 6111 +10
===========================================
+ Hits 2732 3921 +1189
+ Misses 3369 2190 -1179
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
crates/metadata/src/utils.rs
Outdated
} else { | ||
item.trim_end() | ||
pub trait DocString { | ||
fn trim_extra_whitespace(item: Self) -> Self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Add docs with examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got rid of it completely 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constructors need to be tidied up a bit.
Since this will part of ink 4.0
, we are not constrained here by having to make the changes non breaking as we were with scale-info
so a bit more flexibility.
crates/metadata/src/specs.rs
Outdated
@@ -730,7 +800,7 @@ where | |||
|
|||
/// The 4 byte selector to identify constructors and messages | |||
#[derive(Debug, Default, PartialEq, Eq, derive_more::From)] | |||
pub struct Selector([u8; 4]); | |||
pub struct Selector(pub [u8; 4]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the pub
still needed now with the new constructor?
crates/metadata/src/layout/mod.rs
Outdated
@@ -511,7 +519,7 @@ impl FieldLayout { | |||
/// Creates a new field layout. | |||
pub fn new<N, L>(name: N, layout: L) -> Self | |||
where | |||
N: Into<&'static str>, | |||
N: Into<<MetaForm as Form>::String>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just use this constructor and make it generic over form, and remove new_custom
below
crates/metadata/src/layout/mod.rs
Outdated
@@ -241,6 +247,10 @@ where | |||
pub fn ty(&self) -> &F::Type { | |||
&self.ty | |||
} | |||
|
|||
pub fn new_from_ty(key: LayoutKey, ty: <F as Form>::Type) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this constructor should become new
because it allows setting all fields. The existing new<T>
can be renamed to from_key<T>
or similar to be consistent.
crates/metadata/src/layout/mod.rs
Outdated
@@ -525,6 +533,17 @@ impl<F> FieldLayout<F> | |||
where | |||
F: Form, | |||
{ | |||
/// Creates a new custom field layout. | |||
pub fn new_custom<N, L>(name: N, layout: L) -> Self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this in favour of generic new
constructor
crates/metadata/src/specs.rs
Outdated
@@ -942,6 +1024,21 @@ impl<F> EventParamSpec<F> | |||
where | |||
F: Form, | |||
{ | |||
/// Creates a new event paramater specification builder from a custom type. | |||
pub fn new_custom(label: F::String, ty: TypeSpec<F>) -> EventParamSpecBuilder<F> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EventParamSpecBuilder
already has of_type
to mutate the type, so you don't need this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason for it was that Type::new()
is currently only implemented for MetaForm
, but this should be doable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes we should open up any idiomatic new
constructors to be generic
crates/metadata/src/specs.rs
Outdated
@@ -1102,6 +1208,15 @@ impl<F> MessageParamSpec<F> | |||
where | |||
F: Form, | |||
{ | |||
/// Constructs a new message parameter specification via builder. | |||
pub fn new_custom(label: F::String, ty: TypeSpec<F>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can then remove this and use MessageParamSpecBuilder::of_type
crates/metadata/src/specs.rs
Outdated
@@ -366,21 +393,25 @@ impl<S, P> ConstructorSpecBuilder<S, P> { | |||
/// Sets the documentation of the message specification. | |||
pub fn docs<D>(self, docs: D) -> Self | |||
where | |||
D: IntoIterator<Item = &'static str>, | |||
D: IntoIterator<Item = <F as Form>::String>, | |||
F::String: DocString, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
F::String: DocString, | |
F::String: AsRef<[u8]>, |
This might work to avoid requiring the DocString
trait and the new impls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat idea!
crates/metadata/src/specs.rs
Outdated
{ | ||
let mut this = self; | ||
debug_assert!(this.spec.docs.is_empty()); | ||
this.spec.docs = docs | ||
.into_iter() | ||
.map(trim_extra_whitespace) | ||
.map(DocString::trim_extra_whitespace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map(DocString::trim_extra_whitespace) | |
.map(|s| trim_extra_whitespace(s.as_ref())) |
Then you should be able to do something like this.
crates/metadata/src/specs.rs
Outdated
@@ -888,6 +966,10 @@ where | |||
pub fn display_name(&self) -> &DisplayName<F> { | |||
&self.display_name | |||
} | |||
|
|||
pub fn new_from_ty(ty: <F as Form>::Type, display_name: DisplayName<F>) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I would make this the new
constructor, and change the existing new<T>
to e.g. of_type<T>
or maybe with_type<T>
as other constructors are called on this.
crates/metadata/src/utils.rs
Outdated
@@ -58,11 +58,26 @@ where | |||
deserializer.deserialize_str(Visitor) | |||
} | |||
|
|||
/// Strips a single whitespace at the start and removes trailing spaces | |||
pub fn trim_extra_whitespace(item: &str) -> &str { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be able to be restored and remove the duplicate impls, see usage site above with AsRef<[u8]>
bound
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ÀsRef<[u8]>` part is not even needed, was able to nail it using just str refs 👌
@ascjones was able to tidy this up quite a bit and got rid of all the |
Breaking the API here is totally fine since this will be part of a major release |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM just needs CI fixing
Oh it's a |
Yeah right the CI failures seem unrelated to the change. Just got to watch as |
Do you want me to wait with merging? |
In order to fix this issue together with this change, we want to enable metadata construction at runtime. In Solang, we'd like to rely on the official
ink!
crates instead of maintaining our own solution. Additionally, it will be useful for anyone attempting to produce metadata for substrate contracts outsidecargo-contract
(e.g. when other languages want to add a Substrate target).So far, this PR:
Form
String
the default String typeIdeally this should not break any existing API.