diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b77d714d..451055879c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,8 @@ and this project adheres to - cosmwasm-std: Upgrade `serde-json-wasm` dependency to 0.5.0 which adds map support to `to_vec`/`to_binary` and friends. - cosmwasm-std: Implement `AsRef<[u8]>` for `Binary` and `HexBinary` ([#1550]). -- cosmwasm-std: Add constructor `SupplyResponse::new` ([#1552]). +- cosmwasm-std: Allow constructing `SupplyResponse` via a `Default` + implementation ([#1552], [#1560]). [#1436]: https://github.com/CosmWasm/cosmwasm/issues/1436 [#1437]: https://github.com/CosmWasm/cosmwasm/issues/1437 @@ -33,6 +34,7 @@ and this project adheres to [#1550]: https://github.com/CosmWasm/cosmwasm/issues/1550 [#1552]: https://github.com/CosmWasm/cosmwasm/pull/1552 [#1554]: https://github.com/CosmWasm/cosmwasm/pull/1554 +[#1560]: https://github.com/CosmWasm/cosmwasm/pull/1560 ### Changed diff --git a/contracts/reflect/schema/raw/query.json b/contracts/reflect/schema/raw/query.json index 04512e6f3f..914555088d 100644 --- a/contracts/reflect/schema/raw/query.json +++ b/contracts/reflect/schema/raw/query.json @@ -547,7 +547,7 @@ "additionalProperties": false }, { - "description": "returns a ContractInfoResponse with metadata on the contract from the runtime", + "description": "Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime", "type": "object", "required": [ "contract_info" diff --git a/contracts/reflect/schema/reflect.json b/contracts/reflect/schema/reflect.json index ab4e2c0cc6..603c401cd4 100644 --- a/contracts/reflect/schema/reflect.json +++ b/contracts/reflect/schema/reflect.json @@ -1411,7 +1411,7 @@ "additionalProperties": false }, { - "description": "returns a ContractInfoResponse with metadata on the contract from the runtime", + "description": "Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime", "type": "object", "required": [ "contract_info" diff --git a/packages/std/src/query/bank.rs b/packages/std/src/query/bank.rs index e53dbcc9b0..b3a43e11d5 100644 --- a/packages/std/src/query/bank.rs +++ b/packages/std/src/query/bank.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::Coin; +use super::query_response::QueryResponseType; + #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -22,7 +24,7 @@ pub enum BankQuery { } #[cfg(feature = "cosmwasm_1_1")] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub struct SupplyResponse { @@ -32,18 +34,9 @@ pub struct SupplyResponse { } #[cfg(feature = "cosmwasm_1_1")] -impl SupplyResponse { - /// Constructor for testing frameworks such as cw-multi-test. - /// This is required because query response types should be #[non_exhaustive]. - /// As a contract developer you should not need this constructor since - /// query responses are constructed for you via deserialization. - #[doc(hidden)] - pub fn new(amount: Coin) -> Self { - Self { amount } - } -} +impl QueryResponseType for SupplyResponse {} -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct BalanceResponse { /// Always returns a Coin with the requested denom. @@ -51,9 +44,13 @@ pub struct BalanceResponse { pub amount: Coin, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +impl QueryResponseType for BalanceResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct AllBalanceResponse { /// Returns all non-zero coins held by this account. pub amount: Vec, } + +impl QueryResponseType for AllBalanceResponse {} diff --git a/packages/std/src/query/mod.rs b/packages/std/src/query/mod.rs index 67a2fcdb0d..5ca17fe35b 100644 --- a/packages/std/src/query/mod.rs +++ b/packages/std/src/query/mod.rs @@ -7,6 +7,7 @@ use crate::Empty; mod bank; mod ibc; +mod query_response; mod staking; mod wasm; diff --git a/packages/std/src/query/query_response.rs b/packages/std/src/query/query_response.rs new file mode 100644 index 0000000000..dca2e766c9 --- /dev/null +++ b/packages/std/src/query/query_response.rs @@ -0,0 +1,16 @@ +use serde::de::DeserializeOwned; + +/// A marker trait for query response types. +/// +/// Those types have in common that they should be `#[non_exhaustive]` in order +/// to allow adding fields in a backwards compatible way. In contracts they are +/// only constructed through deserialization. We want to make it hard for +/// contract developers to construct those types themselves as this is most likely +/// not what they should do. +/// +/// In hosts they are constructed as follows: +/// - wasmvm: Go types with the same JSON layout +/// - multi-test/cw-sdk: create a default instance and mutate the fields +/// +/// This trait is crate-internal and can change any time. +pub(crate) trait QueryResponseType: Default + DeserializeOwned {} diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs index fee0334635..2be597ae65 100644 --- a/packages/std/src/query/wasm.rs +++ b/packages/std/src/query/wasm.rs @@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize}; use crate::Binary; +use super::query_response::QueryResponseType; + #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -22,12 +24,12 @@ pub enum WasmQuery { /// Key is the raw key used in the contracts Storage key: Binary, }, - /// returns a ContractInfoResponse with metadata on the contract from the runtime + /// Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime ContractInfo { contract_addr: String }, } #[non_exhaustive] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractInfoResponse { pub code_id: u64, /// address that instantiated this contract @@ -40,19 +42,22 @@ pub struct ContractInfoResponse { pub ibc_port: Option, } +impl QueryResponseType for ContractInfoResponse {} + impl ContractInfoResponse { /// Constructor for testing frameworks such as cw-multi-test. /// This is required because query response types should be #[non_exhaustive]. /// As a contract developer you should not need this constructor since /// query responses are constructed for you via deserialization. #[doc(hidden)] + #[deprecated( + note = "Use ContractInfoResponse::default() and mutate the fields you want to set." + )] pub fn new(code_id: u64, creator: impl Into) -> Self { - Self { + ContractInfoResponse { code_id, creator: creator.into(), - admin: None, - pinned: false, - ibc_port: None, + ..Default::default() } } }