1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use crate::prelude::*;
5#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
6use crate::storage_keys::{range_to_bounds, ToByteVec};
7use crate::{Addr, Binary, Checksum};
8#[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
9use core::ops::RangeBounds;
10
11use super::query_response::QueryResponseType;
12
13use crate::utils::impl_hidden_constructor;
14
15#[non_exhaustive]
16#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
17#[serde(rename_all = "snake_case")]
18pub enum WasmQuery {
19 Smart {
23 contract_addr: String,
24 msg: Binary,
26 },
27 Raw {
30 contract_addr: String,
31 key: Binary,
33 },
34 ContractInfo { contract_addr: String },
36 #[cfg(feature = "cosmwasm_1_2")]
38 CodeInfo { code_id: u64 },
39 #[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
47 RawRange {
48 contract_addr: String,
50 start: Option<Binary>,
55 end: Option<Binary>,
57 limit: u16,
63 order: crate::Order,
65 },
66}
67
68impl WasmQuery {
69 #[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
73 pub fn raw_range<'a, R, B>(
74 contract_addr: impl Into<String>,
75 range: R,
76 limit: u16,
77 order: crate::Order,
78 ) -> Self
79 where
80 R: RangeBounds<&'a B>,
81 B: ToByteVec + ?Sized + 'a,
82 {
83 let (start, end) = range_to_bounds(&range);
84
85 WasmQuery::RawRange {
86 contract_addr: contract_addr.into(),
87 start: start.map(Binary::new),
88 end: end.map(Binary::new),
89 limit,
90 order,
91 }
92 }
93}
94
95#[non_exhaustive]
96#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
97pub struct ContractInfoResponse {
98 pub code_id: u64,
99 pub creator: Addr,
101 pub admin: Option<Addr>,
103 pub pinned: bool,
105 pub ibc_port: Option<String>,
107 pub ibc2_port: Option<String>,
109}
110
111impl QueryResponseType for ContractInfoResponse {}
112
113impl_hidden_constructor!(
114 ContractInfoResponse,
115 code_id: u64,
116 creator: Addr,
117 admin: Option<Addr>,
118 pinned: bool,
119 ibc_port: Option<String>,
120 ibc2_port: Option<String>
121);
122
123#[non_exhaustive]
131#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
132pub struct CodeInfoResponse {
133 pub code_id: u64,
134 pub creator: Addr,
136 pub checksum: Checksum,
138}
139
140impl_hidden_constructor!(
141 CodeInfoResponse,
142 code_id: u64,
143 creator: Addr,
144 checksum: Checksum
145);
146
147impl QueryResponseType for CodeInfoResponse {}
148
149#[non_exhaustive]
150#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
151pub struct RawRangeResponse {
152 pub data: Vec<RawRangeEntry>,
154 pub next_key: Option<Binary>,
156}
157
158impl_hidden_constructor!(
159 RawRangeResponse,
160 data: Vec<RawRangeEntry>,
161 next_key: Option<Binary>
162);
163
164pub type RawRangeEntry = (Binary, Binary);
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169 use crate::to_json_binary;
170
171 #[test]
172 fn wasm_query_contract_info_serialization() {
173 let query = WasmQuery::ContractInfo {
174 contract_addr: "aabbccdd456".into(),
175 };
176 let json = to_json_binary(&query).unwrap();
177 assert_eq!(
178 String::from_utf8_lossy(&json),
179 r#"{"contract_info":{"contract_addr":"aabbccdd456"}}"#,
180 );
181 }
182
183 #[test]
184 #[cfg(feature = "cosmwasm_1_2")]
185 fn wasm_query_code_info_serialization() {
186 let query = WasmQuery::CodeInfo { code_id: 70 };
187 let json = to_json_binary(&query).unwrap();
188 assert_eq!(
189 String::from_utf8_lossy(&json),
190 r#"{"code_info":{"code_id":70}}"#,
191 );
192 }
193
194 #[test]
195 fn contract_info_response_serialization() {
196 let response = ContractInfoResponse {
197 code_id: 67,
198 creator: Addr::unchecked("jane"),
199 admin: Some(Addr::unchecked("king")),
200 pinned: true,
201 ibc_port: Some("wasm.123".to_string()),
202 ibc2_port: Some("wasm.123".to_string()),
203 };
204 let json = to_json_binary(&response).unwrap();
205 assert_eq!(
206 String::from_utf8_lossy(&json),
207 r#"{"code_id":67,"creator":"jane","admin":"king","pinned":true,"ibc_port":"wasm.123","ibc2_port":"wasm.123"}"#,
208 );
209 }
210
211 #[test]
212 #[cfg(feature = "cosmwasm_1_2")]
213 fn code_info_response_serialization() {
214 use crate::Checksum;
215
216 let response = CodeInfoResponse {
217 code_id: 67,
218 creator: Addr::unchecked("jane"),
219 checksum: Checksum::from_hex(
220 "f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00",
221 )
222 .unwrap(),
223 };
224 let json = to_json_binary(&response).unwrap();
225 assert_eq!(
226 String::from_utf8_lossy(&json),
227 r#"{"code_id":67,"creator":"jane","checksum":"f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00"}"#,
228 );
229 }
230
231 #[test]
232 #[cfg(all(feature = "cosmwasm_3_0", feature = "iterator"))]
233 fn raw_range_constructor_works() {
234 use crate::Order;
235
236 let query = WasmQuery::raw_range(
237 "contract_addr",
238 &b"asdf"[..]..&b"asdz"[..],
239 100,
240 Order::Ascending,
241 );
242
243 assert_eq!(
244 query,
245 WasmQuery::RawRange {
246 contract_addr: "contract_addr".to_string(),
247 start: Some(Binary::from(b"asdf")),
248 end: Some(Binary::from(b"asdz")),
249 limit: 100,
250 order: Order::Ascending,
251 }
252 );
253
254 let query = WasmQuery::raw_range("contract_addr", b"asdf"..=b"asdz", 100, Order::Ascending);
255 assert_eq!(
256 query,
257 WasmQuery::RawRange {
258 contract_addr: "contract_addr".to_string(),
259 start: Some(Binary::from(b"asdf")),
260 end: Some(Binary::from(b"asdz\0")),
261 limit: 100,
262 order: Order::Ascending,
263 }
264 );
265 }
266
267 #[test]
268 fn raw_range_response_serialization() {
269 let response = RawRangeResponse {
270 data: vec![
271 (Binary::from(b"key"), Binary::from(b"value")),
272 (Binary::from(b"foo"), Binary::from(b"bar")),
273 ],
274 next_key: Some(Binary::from(b"next")),
275 };
276 let json = to_json_binary(&response).unwrap();
277 assert_eq!(
278 String::from_utf8_lossy(&json),
279 r#"{"data":[["a2V5","dmFsdWU="],["Zm9v","YmFy"]],"next_key":"bmV4dA=="}"#,
280 );
281 }
282}