generic_query/
generic_query.rs1use crate::value_ordering::ValueOrdering;
2use cosmwasm_std::{Binary, StdError, StdResult};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5use serde_cw_value::Value;
6
7#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
8pub struct GenericQuery {
9 pub contract_addr: String,
10 pub msg: Binary,
11 pub path_to_value: PathToValue,
12
13 pub ordering: ValueOrdering,
14 pub value: Binary,
15}
16
17#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
19#[serde(rename_all = "snake_case")]
20pub enum ValueIndex {
21 Key(String),
22 Index(u64),
23}
24
25impl From<u64> for ValueIndex {
26 fn from(i: u64) -> Self {
27 Self::Index(i)
28 }
29}
30
31impl From<String> for ValueIndex {
32 fn from(s: String) -> Self {
33 Self::Key(s)
34 }
35}
36
37#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
38pub struct PathToValue(pub Vec<ValueIndex>);
39
40impl From<Vec<ValueIndex>> for PathToValue {
41 fn from(path: Vec<ValueIndex>) -> Self {
42 PathToValue(path)
43 }
44}
45
46impl PathToValue {
47 pub fn find_value<'a>(&self, val: &'a mut Value) -> StdResult<&'a mut Value> {
49 let mut current_val = val;
50 for get in self.0.iter() {
51 match get {
52 ValueIndex::Key(s) => {
53 if let Value::Map(map) = current_val {
54 current_val = map
55 .get_mut(&Value::String(s.clone()))
56 .ok_or_else(|| StdError::generic_err("Invalid key for value"))?;
57 } else {
58 return Err(StdError::generic_err("Failed to get map from this value"));
59 }
60 }
61 ValueIndex::Index(n) => {
62 if let Value::Seq(seq) = current_val {
63 current_val = seq
64 .get_mut(*n as usize)
65 .ok_or_else(|| StdError::generic_err("Invalid index for value"))?;
66 } else {
67 return Err(StdError::generic_err(
68 "Failed to get sequence from this value",
69 ));
70 }
71 }
72 }
73 }
74 Ok(current_val)
75 }
76}