use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::prelude::*;
#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
use crate::storage_keys::{range_to_bounds, ToByteVec};
use crate::{Addr, Binary, Checksum};
#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
use core::ops::RangeBounds;
use super::query_response::QueryResponseType;
use crate::utils::impl_hidden_constructor;
#[non_exhaustive]
#[derive(
Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
)]
#[serde(rename_all = "snake_case")]
pub enum WasmQuery {
Smart {
contract_addr: String,
msg: Binary,
},
Raw {
contract_addr: String,
key: Binary,
},
ContractInfo { contract_addr: String },
#[cfg(feature = "cosmwasm_1_2")]
CodeInfo { code_id: u64 },
#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
RawRange {
contract_addr: String,
start: Option<Binary>,
end: Option<Binary>,
limit: u16,
order: crate::Order,
},
}
impl WasmQuery {
#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
pub fn raw_range<'a, R, B>(
contract_addr: impl Into<String>,
range: R,
limit: u16,
order: crate::Order,
) -> Self
where
R: RangeBounds<&'a B>,
B: ToByteVec + ?Sized + 'a,
{
let (start, end) = range_to_bounds(&range);
WasmQuery::RawRange {
contract_addr: contract_addr.into(),
start: start.map(Binary::new),
end: end.map(Binary::new),
limit,
order,
}
}
}
#[non_exhaustive]
#[derive(
Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
)]
pub struct ContractInfoResponse {
pub code_id: u64,
pub creator: Addr,
pub admin: Option<Addr>,
pub pinned: bool,
pub ibc_port: Option<String>,
pub ibc2_port: Option<String>,
}
impl QueryResponseType for ContractInfoResponse {}
impl_hidden_constructor!(
ContractInfoResponse,
code_id: u64,
creator: Addr,
admin: Option<Addr>,
pinned: bool,
ibc_port: Option<String>,
ibc2_port: Option<String>
);
#[non_exhaustive]
#[derive(
Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, cw_schema::Schemaifier,
)]
pub struct CodeInfoResponse {
pub code_id: u64,
pub creator: Addr,
pub checksum: Checksum,
}
impl_hidden_constructor!(
CodeInfoResponse,
code_id: u64,
creator: Addr,
checksum: Checksum
);
impl QueryResponseType for CodeInfoResponse {}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
pub struct RawRangeResponse {
pub data: Vec<RawRangeEntry>,
pub next_key: Option<Binary>,
}
impl_hidden_constructor!(
RawRangeResponse,
data: Vec<RawRangeEntry>,
next_key: Option<Binary>
);
pub type RawRangeEntry = (Binary, Binary);
#[cfg(test)]
mod tests {
use super::*;
use crate::to_json_binary;
#[test]
fn wasm_query_contract_info_serialization() {
let query = WasmQuery::ContractInfo {
contract_addr: "aabbccdd456".into(),
};
let json = to_json_binary(&query).unwrap();
assert_eq!(
String::from_utf8_lossy(&json),
r#"{"contract_info":{"contract_addr":"aabbccdd456"}}"#,
);
}
#[test]
#[cfg(feature = "cosmwasm_1_2")]
fn wasm_query_code_info_serialization() {
let query = WasmQuery::CodeInfo { code_id: 70 };
let json = to_json_binary(&query).unwrap();
assert_eq!(
String::from_utf8_lossy(&json),
r#"{"code_info":{"code_id":70}}"#,
);
}
#[test]
fn contract_info_response_serialization() {
let response = ContractInfoResponse {
code_id: 67,
creator: Addr::unchecked("jane"),
admin: Some(Addr::unchecked("king")),
pinned: true,
ibc_port: Some("wasm.123".to_string()),
ibc2_port: Some("wasm.123".to_string()),
};
let json = to_json_binary(&response).unwrap();
assert_eq!(
String::from_utf8_lossy(&json),
r#"{"code_id":67,"creator":"jane","admin":"king","pinned":true,"ibc_port":"wasm.123","ibc2_port":"wasm.123"}"#,
);
}
#[test]
#[cfg(feature = "cosmwasm_1_2")]
fn code_info_response_serialization() {
use crate::Checksum;
let response = CodeInfoResponse {
code_id: 67,
creator: Addr::unchecked("jane"),
checksum: Checksum::from_hex(
"f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00",
)
.unwrap(),
};
let json = to_json_binary(&response).unwrap();
assert_eq!(
String::from_utf8_lossy(&json),
r#"{"code_id":67,"creator":"jane","checksum":"f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00"}"#,
);
}
#[test]
#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
fn raw_range_constructor_works() {
use crate::Order;
let query = WasmQuery::raw_range(
"contract_addr",
&b"asdf"[..]..&b"asdz"[..],
100,
Order::Ascending,
);
assert_eq!(
query,
WasmQuery::RawRange {
contract_addr: "contract_addr".to_string(),
start: Some(Binary::from(b"asdf")),
end: Some(Binary::from(b"asdz")),
limit: 100,
order: Order::Ascending,
}
);
let query = WasmQuery::raw_range("contract_addr", b"asdf"..=b"asdz", 100, Order::Ascending);
assert_eq!(
query,
WasmQuery::RawRange {
contract_addr: "contract_addr".to_string(),
start: Some(Binary::from(b"asdf")),
end: Some(Binary::from(b"asdz\0")),
limit: 100,
order: Order::Ascending,
}
);
}
#[test]
fn raw_range_response_serialization() {
let response = RawRangeResponse {
data: vec![
(Binary::from(b"key"), Binary::from(b"value")),
(Binary::from(b"foo"), Binary::from(b"bar")),
],
next_key: Some(Binary::from(b"next")),
};
let json = to_json_binary(&response).unwrap();
assert_eq!(
String::from_utf8_lossy(&json),
r#"{"data":[["a2V5","dmFsdWU="],["Zm9v","YmFy"]],"next_key":"bmV4dA=="}"#,
);
}
}