From 28914bcac71a3536d8ab61752224410014578c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Wo=C5=BAniak?= Date: Wed, 4 Sep 2024 10:51:09 +0200 Subject: [PATCH] feat: Emit new reply dispatch Since this change would be breaking it's hidden behind `sv_replies` feature flag. --- Cargo.lock | 102 +++---- examples/Cargo.toml | 1 + examples/contracts/custom/Cargo.toml | 4 +- examples/contracts/cw1-subkeys/Cargo.toml | 4 +- examples/contracts/cw1-whitelist/Cargo.toml | 4 +- examples/contracts/cw20-base/Cargo.toml | 4 +- .../entry-points-overriding/Cargo.toml | 4 +- .../contracts/generic_contract/Cargo.toml | 4 +- .../generic_contract/src/contract.rs | 5 +- .../generic_iface_on_contract/Cargo.toml | 4 +- .../contracts/generics_forwarded/Cargo.toml | 4 +- .../generics_forwarded/src/contract.rs | 5 +- .../interfaces/custom-and-generic/Cargo.toml | 4 +- examples/interfaces/cw1/Cargo.toml | 4 +- .../interfaces/cw20-allowances/Cargo.toml | 4 +- examples/interfaces/cw20-marketing/Cargo.toml | 4 +- examples/interfaces/cw20-minting/Cargo.toml | 4 +- examples/interfaces/cw4/Cargo.toml | 4 +- examples/interfaces/generic/Cargo.toml | 4 +- examples/interfaces/whitelist/Cargo.toml | 4 +- sylvia-derive/Cargo.toml | 2 + sylvia-derive/src/contract.rs | 11 +- .../src/contract/communication/api.rs | 15 +- .../src/contract/communication/reply.rs | 265 ++++++++++++++++-- sylvia-derive/src/contract/mt.rs | 22 +- sylvia-derive/src/entry_points.rs | 4 + sylvia-derive/src/lib.rs | 10 +- sylvia-derive/src/parser/attributes/msg.rs | 29 +- sylvia/Cargo.toml | 2 + sylvia/src/types.rs | 56 +++- sylvia/tests/messages_generation.rs | 2 + sylvia/tests/replies.rs | 7 +- sylvia/tests/reply.rs | 41 ++- 33 files changed, 479 insertions(+), 164 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c44f981..2c27b17d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,9 +22,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "ark-bls12-381" @@ -212,9 +212,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_panic" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" +checksum = "7782af8f90fe69a4bb41e460abe1727d493403d8b2cc43201a3a3e906b24379f" [[package]] name = "convert_case" @@ -262,7 +262,7 @@ checksum = "029910b409398fdf81955d7301b906caf81f2c42b013ea074fbd89720229c424" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -286,7 +286,7 @@ checksum = "edf5c8adac41bb7751c050d7c4c18675be19ee128714454454575e894424eeef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -392,7 +392,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -477,7 +477,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "unicode-xid", ] @@ -657,9 +657,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -812,11 +812,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -854,9 +854,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13db3d3fde688c61e2446b4d843bc27a7e8af269a69440c0308021dc92333cc" +checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" dependencies = [ "bytes", "prost-derive", @@ -864,22 +864,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18bec9b0adc4eba778b33684b7ba3e7137789434769ee3ce3930463ef904cfca" +checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" dependencies = [ "anyhow", "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -945,9 +945,9 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -979,7 +979,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1003,9 +1003,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -1030,13 +1030,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1047,14 +1047,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -1144,7 +1144,7 @@ dependencies = [ "serde", "sylvia", "sylvia-runtime-macros", - "syn 2.0.75", + "syn 2.0.77", "thiserror", ] @@ -1172,9 +1172,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -1207,7 +1207,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1219,7 +1219,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit", ] [[package]] @@ -1231,17 +1231,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.20" @@ -1252,7 +1241,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -1402,15 +1391,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.18" @@ -1438,7 +1418,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1458,5 +1438,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] diff --git a/examples/Cargo.toml b/examples/Cargo.toml index f99702b2..b156b4a8 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -27,6 +27,7 @@ version = "0.5.0" edition = "2021" [workspace.dependencies] +sylvia = { path = "../sylvia", features = ["sv_replies"] } cw-storage-plus = "2.0.0" cw-utils = "2.0.0" cw2 = "2.0.0" diff --git a/examples/contracts/custom/Cargo.toml b/examples/contracts/custom/Cargo.toml index 9c0b744d..be8e71d7 100644 --- a/examples/contracts/custom/Cargo.toml +++ b/examples/contracts/custom/Cargo.toml @@ -18,7 +18,7 @@ mt = ["library", "sylvia/mt"] [dependencies] cw1 = { path = "../../interfaces/cw1" } cw-storage-plus = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/contracts/cw1-subkeys/Cargo.toml b/examples/contracts/cw1-subkeys/Cargo.toml index bc9c0ff1..3d3d1ed3 100644 --- a/examples/contracts/cw1-subkeys/Cargo.toml +++ b/examples/contracts/cw1-subkeys/Cargo.toml @@ -17,10 +17,10 @@ cw1 = { path = "../../interfaces/cw1" } whitelist = { path = "../../interfaces/whitelist" } cw1-whitelist = { path = "../cw1-whitelist", features = ["library"] } cw2 = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } thiserror = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } cw1-whitelist = { path = "../cw1-whitelist", features = ["mt"] } cw1 = { path = "../../interfaces/cw1", features = ["mt"] } diff --git a/examples/contracts/cw1-whitelist/Cargo.toml b/examples/contracts/cw1-whitelist/Cargo.toml index abf4f881..013f70bb 100644 --- a/examples/contracts/cw1-whitelist/Cargo.toml +++ b/examples/contracts/cw1-whitelist/Cargo.toml @@ -16,7 +16,7 @@ library = [] mt = ["sylvia/mt", "library"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } cw1 = { path = "../../interfaces/cw1" } whitelist = { path = "../../interfaces/whitelist" } cw-storage-plus = { workspace = true } @@ -25,4 +25,4 @@ cw2 = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/contracts/cw20-base/Cargo.toml b/examples/contracts/cw20-base/Cargo.toml index 7df2731f..182d9e1c 100644 --- a/examples/contracts/cw20-base/Cargo.toml +++ b/examples/contracts/cw20-base/Cargo.toml @@ -23,13 +23,13 @@ cw20-allowances = { path = "../../interfaces/cw20-allowances" } cw20-marketing = { path = "../../interfaces/cw20-marketing" } cw20-minting = { path = "../../interfaces/cw20-minting" } semver = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } thiserror = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } cw-utils = { workspace = true } -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } cw20-allowances = { path = "../../interfaces/cw20-allowances", features = [ "mt", ] } diff --git a/examples/contracts/entry-points-overriding/Cargo.toml b/examples/contracts/entry-points-overriding/Cargo.toml index db005f2f..347b6db5 100644 --- a/examples/contracts/entry-points-overriding/Cargo.toml +++ b/examples/contracts/entry-points-overriding/Cargo.toml @@ -18,7 +18,7 @@ mt = ["library", "sylvia/mt"] [dependencies] cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/contracts/generic_contract/Cargo.toml b/examples/contracts/generic_contract/Cargo.toml index b4581cac..63cd5a9c 100644 --- a/examples/contracts/generic_contract/Cargo.toml +++ b/examples/contracts/generic_contract/Cargo.toml @@ -18,10 +18,10 @@ mt = ["library", "sylvia/mt"] [dependencies] cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } cw1 = { path = "../../interfaces/cw1" } generic = { path = "../../interfaces/generic" } custom-and-generic = { path = "../../interfaces/custom-and-generic" } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/contracts/generic_contract/src/contract.rs b/examples/contracts/generic_contract/src/contract.rs index 8d15a695..663042f9 100644 --- a/examples/contracts/generic_contract/src/contract.rs +++ b/examples/contracts/generic_contract/src/contract.rs @@ -1,6 +1,6 @@ use cw_storage_plus::Item; use sylvia::contract; -use sylvia::cw_std::{Reply, Response, StdResult}; +use sylvia::cw_std::{Binary, Response, StdResult, SubMsgResult}; use sylvia::serde::Deserialize; use sylvia::types::{CustomMsg, ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx}; @@ -185,7 +185,8 @@ where fn reply( &self, _ctx: ReplyCtx, - _reply: Reply, + _result: SubMsgResult, + _payload: Binary, ) -> StdResult> { Ok(Response::new()) } diff --git a/examples/contracts/generic_iface_on_contract/Cargo.toml b/examples/contracts/generic_iface_on_contract/Cargo.toml index a164a7e5..4ccb0a2e 100644 --- a/examples/contracts/generic_iface_on_contract/Cargo.toml +++ b/examples/contracts/generic_iface_on_contract/Cargo.toml @@ -18,10 +18,10 @@ mt = ["library", "sylvia/mt"] [dependencies] cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } cw1 = { path = "../../interfaces/cw1" } generic = { path = "../../interfaces/generic" } custom-and-generic = { path = "../../interfaces/custom-and-generic" } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/contracts/generics_forwarded/Cargo.toml b/examples/contracts/generics_forwarded/Cargo.toml index 692e2435..4c1b48b7 100644 --- a/examples/contracts/generics_forwarded/Cargo.toml +++ b/examples/contracts/generics_forwarded/Cargo.toml @@ -18,11 +18,11 @@ mt = ["library", "sylvia/mt"] [dependencies] cw-storage-plus = { workspace = true } cw-utils = { workspace = true } -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } generic = { path = "../../interfaces/generic" } custom-and-generic = { path = "../../interfaces/custom-and-generic/" } cw1 = { path = "../../interfaces/cw1/" } thiserror = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/contracts/generics_forwarded/src/contract.rs b/examples/contracts/generics_forwarded/src/contract.rs index b21e5167..2bc7e8d1 100644 --- a/examples/contracts/generics_forwarded/src/contract.rs +++ b/examples/contracts/generics_forwarded/src/contract.rs @@ -1,7 +1,7 @@ use crate::error::ContractError; use cw_storage_plus::Item; use sylvia::contract; -use sylvia::cw_std::{Reply, Response}; +use sylvia::cw_std::{Binary, Response, SubMsgResult}; use sylvia::serde::Deserialize; use sylvia::types::{ CustomMsg, CustomQuery, ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx, @@ -195,7 +195,8 @@ where fn reply( &self, _ctx: ReplyCtx, - _reply: Reply, + _result: SubMsgResult, + _payload: Binary, ) -> Result, ContractError> { Ok(Response::new()) } diff --git a/examples/interfaces/custom-and-generic/Cargo.toml b/examples/interfaces/custom-and-generic/Cargo.toml index 96043887..8a49f290 100644 --- a/examples/interfaces/custom-and-generic/Cargo.toml +++ b/examples/interfaces/custom-and-generic/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/cw1/Cargo.toml b/examples/interfaces/cw1/Cargo.toml index 59c0b6ce..17ba39ee 100644 --- a/examples/interfaces/cw1/Cargo.toml +++ b/examples/interfaces/cw1/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/cw20-allowances/Cargo.toml b/examples/interfaces/cw20-allowances/Cargo.toml index 9d092387..241f349d 100644 --- a/examples/interfaces/cw20-allowances/Cargo.toml +++ b/examples/interfaces/cw20-allowances/Cargo.toml @@ -12,8 +12,8 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } cw-utils = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/cw20-marketing/Cargo.toml b/examples/interfaces/cw20-marketing/Cargo.toml index 937490d1..26afd608 100644 --- a/examples/interfaces/cw20-marketing/Cargo.toml +++ b/examples/interfaces/cw20-marketing/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/cw20-minting/Cargo.toml b/examples/interfaces/cw20-minting/Cargo.toml index 7e06de53..a285a6a0 100644 --- a/examples/interfaces/cw20-minting/Cargo.toml +++ b/examples/interfaces/cw20-minting/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/cw4/Cargo.toml b/examples/interfaces/cw4/Cargo.toml index 52675131..4292f38f 100644 --- a/examples/interfaces/cw4/Cargo.toml +++ b/examples/interfaces/cw4/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/generic/Cargo.toml b/examples/interfaces/generic/Cargo.toml index 817ad943..cfd31420 100644 --- a/examples/interfaces/generic/Cargo.toml +++ b/examples/interfaces/generic/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/examples/interfaces/whitelist/Cargo.toml b/examples/interfaces/whitelist/Cargo.toml index 409f213e..a18eda93 100644 --- a/examples/interfaces/whitelist/Cargo.toml +++ b/examples/interfaces/whitelist/Cargo.toml @@ -12,7 +12,7 @@ homepage = "https://cosmwasm.com" mt = ["sylvia/mt"] [dependencies] -sylvia = { path = "../../../sylvia" } +sylvia = { workspace = true } [dev-dependencies] -sylvia = { path = "../../../sylvia", features = ["mt"] } +sylvia = { workspace = true, features = ["mt"] } diff --git a/sylvia-derive/Cargo.toml b/sylvia-derive/Cargo.toml index 4918d60c..57ee7c7e 100644 --- a/sylvia-derive/Cargo.toml +++ b/sylvia-derive/Cargo.toml @@ -14,6 +14,7 @@ readme = "../README.md" [features] mt = [] cosmwasm_1_2 = [] +sv_replies = [] [lib] proc-macro = true @@ -42,6 +43,7 @@ sylvia = { path = "../sylvia", features = [ "cosmwasm_1_2", "cosmwasm_1_3", "cosmwasm_1_4", + "sv_replies", ] } serde = { workspace = true } cosmwasm-schema = { workspace = true } diff --git a/sylvia-derive/src/contract.rs b/sylvia-derive/src/contract.rs index 36bfc6d5..ae294c4c 100644 --- a/sylvia-derive/src/contract.rs +++ b/sylvia-derive/src/contract.rs @@ -74,11 +74,12 @@ impl<'a> ContractInput<'a> { item, generics, custom, + error, .. } = self; let multitest_helpers = self.emit_multitest_helpers(); let messages = self.emit_messages(); - let contract_api = Api::new(item, generics, custom).emit(); + let contract_api = Api::new(item, generics, custom, error).emit(); let querier = self.emit_querier(); let executor = self.emit_executor(); let reply = self.emit_reply(); @@ -181,8 +182,12 @@ impl<'a> ContractInput<'a> { } fn emit_reply(&self) -> TokenStream { - let variants = MsgVariants::new(self.item.as_variants(), MsgType::Reply, &[], &None); + if cfg!(feature = "sv_replies") { + let variants = MsgVariants::new(self.item.as_variants(), MsgType::Reply, &[], &None); - Reply::new(&variants).emit() + Reply::new(self.item, &self.generics, &variants).emit() + } else { + quote! {} + } } } diff --git a/sylvia-derive/src/contract/communication/api.rs b/sylvia-derive/src/contract/communication/api.rs index 48d4907e..22fb13d6 100644 --- a/sylvia-derive/src/contract/communication/api.rs +++ b/sylvia-derive/src/contract/communication/api.rs @@ -1,6 +1,6 @@ use crate::crate_module; use crate::parser::variant_descs::AsVariantDescs; -use crate::parser::{Custom, MsgType}; +use crate::parser::{ContractErrorAttr, Custom, MsgType}; use crate::types::msg_variant::MsgVariants; use crate::utils::emit_bracketed_generics; use proc_macro2::TokenStream; @@ -16,10 +16,16 @@ pub struct Api<'a> { sudo_variants: MsgVariants<'a, GenericParam>, generics: &'a [&'a GenericParam], custom: &'a Custom, + error: &'a ContractErrorAttr, } impl<'a> Api<'a> { - pub fn new(source: &'a ItemImpl, generics: &'a [&'a GenericParam], custom: &'a Custom) -> Self { + pub fn new( + source: &'a ItemImpl, + generics: &'a [&'a GenericParam], + custom: &'a Custom, + error: &'a ContractErrorAttr, + ) -> Self { let exec_variants = MsgVariants::new( source.as_variants(), MsgType::Exec, @@ -64,6 +70,7 @@ impl<'a> Api<'a> { sudo_variants, generics, custom, + error, } } @@ -78,7 +85,7 @@ impl<'a> Api<'a> { sudo_variants, generics, custom, - .. + error, } = self; let where_clause = &source.generics.where_clause; @@ -103,6 +110,7 @@ impl<'a> Api<'a> { }; let custom_msg = custom.msg_or_default(); let custom_query = custom.query_or_default(); + let error = &error.error; quote! { impl #bracket_generics #sylvia ::types::ContractApi for #contract_name #where_clause { @@ -118,6 +126,7 @@ impl<'a> Api<'a> { type Querier<'querier> = #sylvia ::types::BoundQuerier<'querier, #custom_query, Self >; type CustomMsg = #custom_msg; type CustomQuery = #custom_query; + type Error = #error; } } } diff --git a/sylvia-derive/src/contract/communication/reply.rs b/sylvia-derive/src/contract/communication/reply.rs index 256a8b7c..8d2cbb88 100644 --- a/sylvia-derive/src/contract/communication/reply.rs +++ b/sylvia-derive/src/contract/communication/reply.rs @@ -1,60 +1,269 @@ use convert_case::{Case, Casing}; -use itertools::Itertools; use proc_macro2::TokenStream; +use proc_macro_error::emit_error; use quote::quote; -use syn::{GenericParam, Ident}; +use syn::fold::Fold; +use syn::{parse_quote, GenericParam, Ident, ItemImpl, Type}; -use crate::types::msg_variant::MsgVariants; +use crate::crate_module; +use crate::fold::StripGenerics; +use crate::parser::attributes::msg::ReplyOn; +use crate::parser::MsgType; +use crate::types::msg_variant::{MsgVariant, MsgVariants}; pub struct Reply<'a> { - variants: &'a MsgVariants<'a, GenericParam>, + source: &'a ItemImpl, + generics: &'a [&'a GenericParam], + reply_data: Vec>, } impl<'a> Reply<'a> { - pub fn new(variants: &'a MsgVariants<'a, GenericParam>) -> Self { - Self { variants } + pub fn new( + source: &'a ItemImpl, + generics: &'a [&'a GenericParam], + variants: &'a MsgVariants<'a, GenericParam>, + ) -> Self { + let reply_data = variants.as_reply_data(); + + Self { + source, + generics, + reply_data, + } } pub fn emit(&self) -> TokenStream { - let unique_handlers = self.emit_reply_ids(); + let unique_handlers: Vec<_> = self.emit_reply_ids().collect(); + let dispatch = self.emit_dispatch(); quote! { #(#unique_handlers)* + + #dispatch } } - fn emit_reply_ids(&self) -> impl Iterator + 'a { - self.variants - .as_reply_ids() - .enumerate() - .map(|(id, reply_id)| { - let id = id as u64; + /// Generates dispatch method that matches over every generated `ReplyId` + /// and dispatches depending on the [`ReplyOn`](crate::parser::attributes::msg::ReplyOn). + pub fn emit_dispatch(&self) -> TokenStream { + let sylvia = crate_module(); + let Self { + source, + generics, + reply_data, + .. + } = self; + + let msg_ty = MsgType::Reply; + let contract = &source.self_ty; + let where_clause = &source.generics.where_clause; + let custom_query = parse_quote!( < #contract as #sylvia ::types::ContractApi>::CustomQuery); + let custom_msg = parse_quote!( < #contract as #sylvia ::types::ContractApi>::CustomMsg); + let error = parse_quote!( < #contract as #sylvia ::types::ContractApi>::Error); + let ctx_params = msg_ty.emit_ctx_params(&custom_query); + let ret_type = msg_ty.emit_result_type(&custom_msg, &error); + + let match_arms = reply_data.iter().map(|data| { + let result_match_arms = data.handlers.iter().map(|(function_name, reply_on)| { + let result_match_arm = reply_on.emit_match_arm(); + let result_match_arm_body = self.emit_match_arm_body(reply_on, function_name); quote! { - pub const #reply_id : u64 = #id ; + #result_match_arm => { + #result_match_arm_body + } } - }) + }); + // TODO: Add proper result forwarding. + let default_match_arm = if !data + .handlers + .iter() + .any(|(_, reply_on)| reply_on == &ReplyOn::Always) + { + quote! { + _ => Ok( #sylvia ::cw_std::Response::new()) + + } + } else { + quote! {} + }; + + let reply_id = &data.reply_id; + quote! { + #reply_id => { + match result { + #(#result_match_arms,)* + #default_match_arm + } + } + } + }); + + quote! { + pub fn dispatch_reply < #(#generics),* >( #ctx_params , msg: #sylvia ::cw_std::Reply, contract: #contract ) -> #ret_type #where_clause { + let #sylvia ::cw_std::Reply { + id, + payload, + gas_used, + result, + } = msg; + + match id { + #(#match_arms,)* + // TODO: Add proper result forwarding. + _ => Ok( #sylvia ::cw_std::Response::new()) + } + } + } + } + + /// Generates `ReplyId`s for every unique + /// [`reply_handler`](crate::parser::attributes::msg::MsgAttr::reply_handlers) and + /// [`function_name`](crate::types::msg_variant::MsgVariant::function_name) not anotated with + /// the `#[sv::msg(..)]` attribute with the `handlers` parameter. + fn emit_reply_ids(&'a self) -> impl Iterator + 'a { + self.reply_data.iter().enumerate().map(|(id, data)| { + let id = id as u64; + let reply_id = &data.reply_id; + quote! { + pub const #reply_id : u64 = #id ; + } + }) + } + + fn emit_match_arm_body(&self, reply_on: &ReplyOn, function_name: &Ident) -> TokenStream { + let Self { + source, generics, .. + } = self; + + let sylvia = crate_module(); + let contract = &source.self_ty; + let contract_turbo: Type = if !generics.is_empty() { + let contract_name = StripGenerics.fold_type((*contract.clone()).clone()); + parse_quote! { #contract_name :: < #(#generics),* > } + } else { + parse_quote! { #contract } + }; + + match reply_on { + ReplyOn::Success => quote! { + #[allow(deprecated)] + let #sylvia ::cw_std::SubMsgResponse { events, data, msg_responses} = response; + #contract_turbo ::new(). #function_name ((deps, env, gas_used, events, msg_responses).into(), data, payload) + }, + ReplyOn::Failure => quote! { + #contract_turbo ::new(). #function_name ((deps, env, gas_used, vec![], vec![]).into(), error, payload) + }, + ReplyOn::Always => quote! { + #contract_turbo ::new(). #function_name ((deps, env, gas_used, vec![], vec![]).into(), result, payload) + }, + } } } trait ReplyVariants<'a> { - fn as_reply_ids(&'a self) -> impl Iterator + 'a; + /// Maps to [Vec]. + /// Validation for duplicates and overlaps should be done in this method. + fn as_reply_data(&self) -> Vec; } impl<'a> ReplyVariants<'a> for MsgVariants<'a, GenericParam> { - fn as_reply_ids(&'a self) -> impl Iterator + 'a { - self.variants() - .flat_map(|variant| { - if variant.msg_attr().handlers().is_empty() { - return vec![variant.function_name()]; - } - variant.msg_attr().handlers().iter().collect() - }) - .unique() + fn as_reply_data(&self) -> Vec { + let mut reply_data: Vec = vec![]; + + self + .variants() + .flat_map(ReplyVariant::as_reply_data) + .for_each(|(reply_id, function_name, reply_on)| { + match reply_data.iter_mut().find(|existing_data| existing_data.reply_id == reply_id) { + Some(existing_data) + if existing_data.handlers + .iter() + .any(|(_, prev_reply_on)| { + prev_reply_on.excludes(&reply_on) + }) => + { + existing_data.handlers.iter().for_each(|(prev_function_name, prev_reply_on)|{ + emit_error!(reply_id.span(), "Duplicated reply handler."; + note = prev_function_name.span() => format!("Previous definition of handler={} for reply_on={}", existing_data.reply_id.to_string(), prev_reply_on ) + ) + }) + }, + Some(existing_data) => { + existing_data.handlers.push((function_name, reply_on)) + }, + None => reply_data.push(ReplyData::new (reply_id, function_name, reply_on)), + }}); + + reply_data + } +} + +struct ReplyData<'a> { + pub reply_id: Ident, + pub handlers: Vec<(&'a Ident, ReplyOn)>, +} + +impl<'a> ReplyData<'a> { + pub fn new(reply_id: Ident, function_name: &'a Ident, reply_on: ReplyOn) -> Self { + Self { + reply_id, + handlers: vec![(function_name, reply_on)], + } + } +} + +trait ReplyVariant<'a> { + fn as_handlers(&'a self) -> Vec<&'a Ident>; + fn as_reply_data(&self) -> Vec<(Ident, &Ident, ReplyOn)>; +} + +impl<'a> ReplyVariant<'a> for MsgVariant<'a> { + fn as_handlers(&'a self) -> Vec<&'a Ident> { + if self.msg_attr().handlers().is_empty() { + return vec![self.function_name()]; + } + self.msg_attr().handlers().iter().collect() + } + + fn as_reply_data(&self) -> Vec<(Ident, &Ident, ReplyOn)> { + self.as_handlers() + .iter() .map(|handler| { - let reply_id = - format! {"{}_REPLY_ID", handler.to_string().to_case(Case::UpperSnake)}; - Ident::new(&reply_id, handler.span()) + ( + handler.as_reply_id(), + self.function_name(), + self.msg_attr().reply_on(), + ) }) + .collect() + } +} + +/// Maps self to a reply id +trait AsReplyId { + fn as_reply_id(&self) -> Ident; +} + +impl AsReplyId for Ident { + fn as_reply_id(&self) -> Ident { + let reply_id = format! {"{}_REPLY_ID", self.to_string().to_case(Case::UpperSnake)}; + Ident::new(&reply_id, self.span()) + } +} + +trait ReplyOnMethods { + fn emit_match_arm(&self) -> TokenStream; +} + +impl ReplyOnMethods for ReplyOn { + fn emit_match_arm(&self) -> TokenStream { + let sylvia = crate_module(); + + match self { + ReplyOn::Success => quote! { #sylvia ::cw_std::SubMsgResult::Ok(response) }, + ReplyOn::Failure => quote! { #sylvia ::cw_std::SubMsgResult::Err(error) }, + ReplyOn::Always => quote! { _ }, + } } } diff --git a/sylvia-derive/src/contract/mt.rs b/sylvia-derive/src/contract/mt.rs index 46161460..5a238f85 100644 --- a/sylvia-derive/src/contract/mt.rs +++ b/sylvia-derive/src/contract/mt.rs @@ -531,10 +531,24 @@ impl<'a> MtHelpers<'a> { None => reply_variants .get_only_variant() .as_ref() - .map(|reply| { - let reply_name = reply.name().to_case(Case::Snake); - quote! { - self. #reply_name ((deps, env).into(), msg).map_err(Into::into) + .map(|_reply| { + let contract_ident = get_ident_from_type(contract_name); + let contract_turbo = if !generic_params.is_empty() { + quote! { #contract_ident ::< #(#generic_params,)* > } + } else { + quote! { #contract_ident } + }; + + if cfg!(feature = "sv_replies") { + quote! { + let contract = #contract_turbo ::new(); + dispatch_reply(deps, env, msg, contract).map_err(Into::into) + } + } else { + let reply_name = _reply.name().to_case(Case::Snake); + quote! { + self. #reply_name ((deps, env).into(), msg).map_err(Into::into) + } } }) .unwrap_or_else(|| { diff --git a/sylvia-derive/src/entry_points.rs b/sylvia-derive/src/entry_points.rs index 33544c59..11591f2a 100644 --- a/sylvia-derive/src/entry_points.rs +++ b/sylvia-derive/src/entry_points.rs @@ -201,6 +201,10 @@ impl<'a> EntryPoints<'a> { _ => quote! { msg: < #contract as #sylvia ::types::ContractApi> :: #associated_name }, }; let dispatch = match msg_ty { + MsgType::Reply if cfg!(feature = "sv_replies") => quote! { + let contract = #contract_turbo ::new(); + sv::dispatch_reply(deps, env, msg, contract).map_err(Into::into) + }, MsgType::Reply => quote! { #contract_turbo ::new(). #reply((deps, env).into(), msg).map_err(Into::into) }, diff --git a/sylvia-derive/src/lib.rs b/sylvia-derive/src/lib.rs index f581f8aa..3403daf9 100644 --- a/sylvia-derive/src/lib.rs +++ b/sylvia-derive/src/lib.rs @@ -264,7 +264,7 @@ fn interface_impl(_attr: TokenStream2, item: TokenStream2) -> TokenStream2 { /// ## Example usage /// ```rust /// # use sylvia::types::{ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx}; -/// # use sylvia::cw_std::{Response, StdError, Reply}; +/// # use sylvia::cw_std::{Binary, Response, StdError, SubMsgResult}; /// # use cw_storage_plus::Item; /// # use thiserror::Error; /// # @@ -310,7 +310,7 @@ fn interface_impl(_attr: TokenStream2, item: TokenStream2) -> TokenStream2 { /// } /// /// #[sv::msg(reply)] -/// fn reply(&self, ctx: ReplyCtx, reply: Reply) -> Result { +/// fn reply(&self, ctx: ReplyCtx, result: SubMsgResult, payload: Binary) -> Result { /// # Ok(Response::new()) /// } /// @@ -326,7 +326,7 @@ fn interface_impl(_attr: TokenStream2, item: TokenStream2) -> TokenStream2 { /// /// ```rust /// # use sylvia::types::{ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx}; -/// # use sylvia::cw_std::{Response, StdError}; +/// # use sylvia::cw_std::{Binary, Response, StdError, SubMsgResult}; /// # use cw_storage_plus::Item; /// # use thiserror::Error; /// # @@ -655,7 +655,7 @@ fn contract_impl(attr: TokenStream2, item: TokenStream2) -> TokenStream2 { /// ## Example usage /// ```rust /// # use sylvia::types::{ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx}; -/// # use sylvia::cw_std::{Reply, Response, StdResult}; +/// # use sylvia::cw_std::{Binary, Reply, Response, StdResult, SubMsgResult}; /// # /// pub struct SvContract; /// @@ -687,7 +687,7 @@ fn contract_impl(attr: TokenStream2, item: TokenStream2) -> TokenStream2 { /// # } /// # /// # #[sv::msg(reply)] -/// # fn reply(&self, ctx: ReplyCtx, reply: Reply) -> StdResult { +/// # fn reply(&self, ctx: ReplyCtx, result: SubMsgResult, payload: Binary) -> StdResult { /// # Ok(Response::new()) /// # } /// # diff --git a/sylvia-derive/src/parser/attributes/msg.rs b/sylvia-derive/src/parser/attributes/msg.rs index 288ccfa7..3f4d1e45 100644 --- a/sylvia-derive/src/parser/attributes/msg.rs +++ b/sylvia-derive/src/parser/attributes/msg.rs @@ -67,7 +67,7 @@ impl Parse for ArgumentParser { } /// Representation of `reply_on` parameter in `#[sv::msg(reply(...))]` attribute. -#[derive(Debug, Default, Clone)] +#[derive(Copy, Debug, Default, Clone, PartialEq)] pub enum ReplyOn { Success, Failure, @@ -75,6 +75,16 @@ pub enum ReplyOn { Always, } +impl std::fmt::Display for ReplyOn { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ReplyOn::Success => f.write_str("success"), + ReplyOn::Failure => f.write_str("failure"), + ReplyOn::Always => f.write_str("always"), + } + } +} + impl ReplyOn { pub fn new(reply_on: Ident) -> Result { match reply_on.to_string().as_str() { @@ -87,6 +97,15 @@ impl ReplyOn { )), } } + + /// Checks if two [ReplyOn] values are unique and if [ReplyOn::Always] is not one of them as it is exclusive + /// and cannot be paired with any other value. + pub fn excludes(&self, other: &Self) -> bool { + let are_equal = self == other; + let is_any_always = self == &ReplyOn::Always || other == &ReplyOn::Always; + + are_equal || is_any_always + } } /// Parsed representation of `#[sv::msg(...)]` attribute. @@ -95,7 +114,7 @@ pub struct MsgAttr { msg_type: MsgType, query_resp_type: Option, reply_handlers: Vec, - _reply_on: ReplyOn, + reply_on: ReplyOn, } impl MsgAttr { @@ -117,6 +136,10 @@ impl MsgAttr { pub fn handlers(&self) -> &[Ident] { &self.reply_handlers } + + pub fn reply_on(&self) -> ReplyOn { + self.reply_on + } } impl PartialEq for MsgAttr { @@ -139,7 +162,7 @@ impl Parse for MsgAttr { msg_type, query_resp_type, reply_handlers, - _reply_on: reply_on.unwrap_or_default(), + reply_on: reply_on.unwrap_or_default(), }) } } diff --git a/sylvia/Cargo.toml b/sylvia/Cargo.toml index 92df9d7a..fa4cf17b 100644 --- a/sylvia/Cargo.toml +++ b/sylvia/Cargo.toml @@ -38,6 +38,8 @@ cosmwasm_2_0 = [ "cw-multi-test/cosmwasm_2_0", "cosmwasm_1_4", ] +# Enables better repli +sv_replies = ["sylvia-derive/sv_replies"] [dependencies] sylvia-derive = { workspace = true } diff --git a/sylvia/src/types.rs b/sylvia/src/types.rs index 0c0e9378..cbf12d38 100644 --- a/sylvia/src/types.rs +++ b/sylvia/src/types.rs @@ -1,5 +1,7 @@ //! Module providing utilities to build and use sylvia contracts. use cosmwasm_std::{Binary, Coin, Deps, DepsMut, Empty, Env, MessageInfo, WasmMsg}; +#[cfg(feature = "sv_replies")] +use cosmwasm_std::{Event, MsgResponse}; use derivative::Derivative; use schemars::JsonSchema; use serde::de::DeserializeOwned; @@ -441,45 +443,50 @@ impl<'a, Contract: ?Sized> AsRef for Remote<'a, Contract> { } } -/// Represantation of `reply` context received in entry point as -/// (DepsMut, Env) tuple. +/// Represantation of `reply` context received in entry point. +#[cfg(feature = "sv_replies")] pub struct ReplyCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { pub deps: DepsMut<'a, C>, pub env: Env, + pub gas_used: u64, + pub events: Vec, + pub msg_responses: Vec, } -/// Represantation of `reply` context received in entry point as -/// (DepsMut, Env) tuple. +/// Represantation of `reply` context received in entry point. +#[cfg(not(feature = "sv_replies"))] +pub struct ReplyCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { + pub deps: DepsMut<'a, C>, + pub env: Env, +} + +/// Represantation of `migrate` context received in entry point. pub struct MigrateCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { pub deps: DepsMut<'a, C>, pub env: Env, } -/// Represantation of `reply` context received in entry point as -/// (DepsMut, Env, MessageInfo) tuple. +/// Represantation of `execute` context received in entry point. pub struct ExecCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { pub deps: DepsMut<'a, C>, pub env: Env, pub info: MessageInfo, } -/// Represantation of `instantiate` context received in entry point as -/// (DepsMut, Env, MessageInfo) tuple. +/// Represantation of `instantiate` context received in entry point. pub struct InstantiateCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { pub deps: DepsMut<'a, C>, pub env: Env, pub info: MessageInfo, } -/// Represantation of `query` context received in entry point as -/// (Deps, Env) tuple. +/// Represantation of `query` context received in entry point. pub struct QueryCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { pub deps: Deps<'a, C>, pub env: Env, } -/// Represantation of `sudo` context received in entry point as -/// (DepsMut, Env) tuple. +/// Represantation of `sudo` context received in entry point. pub struct SudoCtx<'a, C: cosmwasm_std::CustomQuery = Empty> { pub deps: DepsMut<'a, C>, pub env: Env, @@ -520,6 +527,30 @@ impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env)> for MigrateCt } } +#[cfg(feature = "sv_replies")] +impl<'a, C: cosmwasm_std::CustomQuery> + From<(DepsMut<'a, C>, Env, u64, Vec, Vec)> for ReplyCtx<'a, C> +{ + fn from( + (deps, env, gas_used, events, msg_responses): ( + DepsMut<'a, C>, + Env, + u64, + Vec, + Vec, + ), + ) -> Self { + Self { + deps, + env, + gas_used, + events, + msg_responses, + } + } +} + +#[cfg(not(feature = "sv_replies"))] impl<'a, C: cosmwasm_std::CustomQuery> From<(DepsMut<'a, C>, Env)> for ReplyCtx<'a, C> { fn from((deps, env): (DepsMut<'a, C>, Env)) -> Self { Self { deps, env } @@ -588,4 +619,5 @@ pub trait ContractApi { type Remote<'remote>; type CustomMsg: CustomMsg; type CustomQuery: CustomQuery; + type Error: From; } diff --git a/sylvia/tests/messages_generation.rs b/sylvia/tests/messages_generation.rs index a752ee6a..439febaa 100644 --- a/sylvia/tests/messages_generation.rs +++ b/sylvia/tests/messages_generation.rs @@ -1,3 +1,4 @@ +#![cfg(not(feature = "sv_replies"))] use std::fmt::Debug; use std::str::FromStr; @@ -65,6 +66,7 @@ pub mod interface { } mod contract { + use cosmwasm_std::{Binary, SubMsgResult}; use sylvia::contract; use sylvia::cw_std::{Addr, Reply, Response, StdResult}; use sylvia::types::{ExecCtx, InstantiateCtx, MigrateCtx, QueryCtx, ReplyCtx, SudoCtx}; diff --git a/sylvia/tests/replies.rs b/sylvia/tests/replies.rs index 663b255f..16c05b39 100644 --- a/sylvia/tests/replies.rs +++ b/sylvia/tests/replies.rs @@ -1,3 +1,5 @@ +#![cfg(not(feature = "sv_replies"))] + #[cfg(all(test, feature = "mt"))] use cw_multi_test::IntoBech32; use sylvia::cw_std::testing::{mock_dependencies, mock_env}; @@ -32,10 +34,11 @@ mod noop_contract { } mod reply_contract { + use cosmwasm_std::{Binary, Reply, SubMsgResult}; use sylvia::types::{ExecCtx, InstantiateCtx, ReplyCtx}; use sylvia::{contract, entry_points}; - use sylvia::cw_std::{to_json_binary, Reply, Response, StdResult, SubMsg, WasmMsg}; + use sylvia::cw_std::{to_json_binary, Response, StdResult, SubMsg, WasmMsg}; use super::noop_contract; @@ -69,7 +72,7 @@ mod reply_contract { } #[sv::msg(reply)] - fn reply(&self, _ctx: ReplyCtx, _msg: Reply) -> StdResult { + fn reply(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { let resp = Response::new().set_data(to_json_binary("data")?); Ok(resp) } diff --git a/sylvia/tests/reply.rs b/sylvia/tests/reply.rs index e8599da8..f67d9f23 100644 --- a/sylvia/tests/reply.rs +++ b/sylvia/tests/reply.rs @@ -1,5 +1,7 @@ +#![cfg(feature = "sv_replies")] +use cosmwasm_std::{Binary, SubMsgResult}; use sylvia::contract; -use sylvia::cw_std::{Reply, Response, StdResult}; +use sylvia::cw_std::{Response, StdResult}; use sylvia::types::{InstantiateCtx, ReplyCtx}; pub struct Contract; @@ -16,31 +18,56 @@ impl Contract { } #[sv::msg(reply)] - fn clean(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { + fn clean( + &self, + _ctx: ReplyCtx, + _result: SubMsgResult, + _payload: Binary, + ) -> StdResult { Ok(Response::new()) } #[allow(dead_code)] #[sv::msg(reply, handlers(handler_one, handler_two))] - fn custom_handlers(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { + fn custom_handlers( + &self, + _ctx: ReplyCtx, + _result: SubMsgResult, + _payload: Binary, + ) -> StdResult { Ok(Response::new()) } #[allow(dead_code)] #[sv::msg(reply, reply_on = success)] - fn reply_on(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { + fn reply_on( + &self, + _ctx: ReplyCtx, + _data: Option, + _payload: Binary, + ) -> StdResult { Ok(Response::new()) } #[allow(dead_code)] #[sv::msg(reply, reply_on = always)] - fn reply_on_always(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { + fn reply_on_always( + &self, + _ctx: ReplyCtx, + _result: SubMsgResult, + _payload: Binary, + ) -> StdResult { Ok(Response::new()) } #[allow(dead_code)] - #[sv::msg(reply, handlers(handler_one, handler_two), reply_on = failure)] - fn both_parameters(&self, _ctx: ReplyCtx, _reply: Reply) -> StdResult { + #[sv::msg(reply, handlers(reply_on), reply_on = failure)] + fn both_parameters( + &self, + _ctx: ReplyCtx, + _error: String, + _payload: Binary, + ) -> StdResult { Ok(Response::new()) } }