-
Notifications
You must be signed in to change notification settings - Fork 16
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
feat: Add InstantiateBuilder and SubMsg trait #437
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feat/replies #437 +/- ##
================================================
+ Coverage 71.23% 72.20% +0.96%
================================================
Files 54 56 +2
Lines 3299 3457 +158
================================================
+ Hits 2350 2496 +146
- Misses 949 961 +12 ☔ View full report in Codecov by Sentry. |
d6c31de
to
d7e179a
Compare
d7e179a
to
8140714
Compare
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.
In general I like the API, but I don't like that the tests are just expanded to generics to cover more cases. I'd prefer to have separated tests for simple things, and for generics. This way tests serves as better examples, and also if something breaks it is more clear where it breaks.
use sylvia::{contract, entry_points}; | ||
|
||
use sylvia::cw_std::Response; | ||
|
||
pub struct NoopContract; | ||
pub struct NoopContract<M, Q> { | ||
_phantom: std::marker::PhantomData<(M, Q)>, |
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.
Do we need to extend this contract to be generic? Tests often serves as examples, I think it would be good to maintain simple contracts testing basics, and then separate generic/more complex contract testing the more specific things.
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.
We could, however this would more or less lead to duplication of these tests and contracts.
Also we decided that using generic for custom message and custom query is a good practice.
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. The only thing that we discussed are the replies after instantiation procedure. Something like callback_{name_of_the_method}
@@ -266,12 +366,13 @@ impl<'a> ReplyVariant<'a> for MsgVariant<'a> { | |||
self.msg_attr().handlers().iter().collect() | |||
} | |||
|
|||
fn as_reply_data(&self) -> Vec<(Ident, &Ident, ReplyOn)> { | |||
fn as_reply_data(&self) -> Vec<(Ident, &Ident, &Ident, ReplyOn)> { |
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.
Let's have a struct instead of tuple in the result of this method
@@ -255,7 +355,7 @@ fn emit_failure_match_arm( | |||
|
|||
trait ReplyVariant<'a> { | |||
fn as_handlers(&'a self) -> Vec<&'a Ident>; | |||
fn as_reply_data(&self) -> Vec<(Ident, &Ident, ReplyOn)>; | |||
fn as_reply_data(&self) -> Vec<(Ident, &Ident, &Ident, ReplyOn)>; |
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.
Let's have a struct instead of tuple in the result of this method
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 didn't want to create an intermediate struct for that, but I will just move this logic to the as_reply_data
method.
If it's okay with you I would do that in the latest PR to avoid conflicts.
} else if is_failure { | ||
quote! { #sylvia ::cw_std::ReplyOn::Error } | ||
} else { | ||
// This should never happen |
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.
Why this should never happen? If so, the code itself should prevent such a path (and raise an error in compilation time to the user)
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.
It will earlier while parsing. We support Success
, Failure
, and Always
, as specifying logic that would Never
be called makes no sense.
I will add better comment there.
@@ -146,28 +216,31 @@ impl<'a> ReplyVariants<'a> for MsgVariants<'a, GenericParam> { | |||
/// Maps single reply id with its handlers. | |||
struct ReplyData<'a> { | |||
pub reply_id: Ident, | |||
pub handler_name: &'a Ident, |
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.
What's the difference between handler_name and handlers? Both names suggest that they are somehow related to each other
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 will figure out some better naming.
The handler_name
is either method name or value from handlers
parameter. The reply_id
is constructed based on it.
The handlers are pairs of method names and reply_on
values to determine what logic in which scenario should be called.
self.last_reply.save(ctx.deps.storage, &ALWAYS_REPLY_ID)?; | ||
|
||
Ok(Response::new()) | ||
} | ||
|
||
#[sv::msg(exec)] | ||
fn send_cosmos_messages(&self, ctx: ExecCtx<Q>) -> Result<Response<M>, ContractError> { |
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.
Do we use this method?
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.
Good catch. I missed to call it in the test.
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 overall. A neat feature is delivered. I don't see anything harmful, so approving 👍
use crate::types::msg_variant::MsgVariant; | ||
use crate::utils::{get_ident_from_type, SvCasing}; | ||
|
||
pub struct InstantiateBuilder<'a> { |
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.
Could this InstantiateBuilder::new(...).emit()
dance be replaced by a single emit_instantiate_builder
function?
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.
It might. This is just how all the code looks like in the sylvia-derive
.
The benefit is that in some cases we want to do some validation and data preparation in the new
method which makes the emit
method more readable.
fn #method_name < #(#used_generics),* > (code_id: u64, #(#parameters,)* ) -> #sylvia ::cw_std::StdResult< #sylvia ::builder::instantiate::InstantiateBuilder> #where_clause { | ||
let msg = #msg_name ::< #(#used_generics),* > ::new( #(#fields_names),* ); | ||
let msg = #sylvia ::cw_std::to_json_binary(&msg)?; | ||
Ok( #sylvia ::builder::instantiate::InstantiateBuilder::new(msg, code_id)) |
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.
Pretty cool that you're exposing a builder API for custom structs decorated with the Sylvia macro!
&segment.ident | ||
} | ||
|
||
pub fn emit_turbofish(ty: &Type, generics: &[&GenericParam]) -> Type { |
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 is a good opportunity for a very special message.
No description provided.