andromeda_data_storage/
primitive.rs1use andromeda_std::{amp::AndrAddr, andr_exec, andr_instantiate, andr_query};
2use cosmwasm_schema::{cw_serde, schemars::Map, QueryResponses};
3use cosmwasm_std::{Addr, Binary, Coin, Decimal, StdError, Uint128};
4
5#[andr_instantiate]
6#[cw_serde]
7pub struct InstantiateMsg {
8 pub restriction: PrimitiveRestriction,
9}
10
11#[andr_exec]
12#[cw_serde]
13pub enum ExecuteMsg {
14 SetValue {
16 key: Option<String>,
17 value: Primitive,
18 },
19 DeleteValue {
21 key: Option<String>,
22 },
23 UpdateRestriction {
24 restriction: PrimitiveRestriction,
25 },
26}
27
28#[andr_query]
29#[cw_serde]
30#[derive(QueryResponses)]
31pub enum QueryMsg {
32 #[returns(GetValueResponse)]
33 GetValue { key: Option<String> },
34 #[returns(Vec<String>)]
35 AllKeys {},
36 #[returns(Vec<String>)]
37 OwnerKeys { owner: AndrAddr },
38}
39
40#[cw_serde]
41pub enum Primitive {
42 Uint128(Uint128),
43 Decimal(Decimal),
44 Coin(Coin),
45 Addr(Addr),
46 String(String),
47 Bool(bool),
48 Vec(Vec<Primitive>),
49 Binary(Binary),
50 Object(Map<String, Primitive>),
51}
52
53#[cw_serde]
54pub enum PrimitiveRestriction {
55 Private,
56 Public,
57 Restricted,
58}
59
60fn parse_error(type_name: String) -> StdError {
61 StdError::ParseErr {
62 target_type: type_name.clone(),
63 msg: format!("Primitive is not a {type_name}"),
64 }
65}
66
67impl From<String> for Primitive {
68 fn from(value: String) -> Self {
69 Primitive::String(value)
70 }
71}
72
73impl From<Uint128> for Primitive {
74 fn from(value: Uint128) -> Self {
75 Primitive::Uint128(value)
76 }
77}
78
79impl From<Decimal> for Primitive {
80 fn from(value: Decimal) -> Self {
81 Primitive::Decimal(value)
82 }
83}
84
85impl From<bool> for Primitive {
86 fn from(value: bool) -> Self {
87 Primitive::Bool(value)
88 }
89}
90
91impl From<Coin> for Primitive {
92 fn from(value: Coin) -> Self {
93 Primitive::Coin(value)
94 }
95}
96
97impl From<Addr> for Primitive {
98 fn from(value: Addr) -> Self {
99 Primitive::Addr(value)
100 }
101}
102
103impl From<Vec<Primitive>> for Primitive {
104 fn from(value: Vec<Primitive>) -> Self {
105 Primitive::Vec(value)
106 }
107}
108
109impl From<Binary> for Primitive {
110 fn from(value: Binary) -> Self {
111 Primitive::Binary(value)
112 }
113}
114
115impl From<Map<String, Primitive>> for Primitive {
116 fn from(value: Map<String, Primitive>) -> Self {
117 Primitive::Object(value)
118 }
119}
120
121impl Primitive {
124 pub fn try_get_uint128(&self) -> Result<Uint128, StdError> {
125 match self {
126 Primitive::Uint128(value) => Ok(*value),
127 _ => Err(parse_error(String::from("Uint128"))),
128 }
129 }
130
131 pub fn try_get_decimal(&self) -> Result<Decimal, StdError> {
132 match self {
133 Primitive::Decimal(value) => Ok(*value),
134 _ => Err(parse_error(String::from("Decimal"))),
135 }
136 }
137
138 pub fn try_get_string(&self) -> Result<String, StdError> {
139 match self {
140 Primitive::String(value) => Ok(value.to_string()),
141 _ => Err(parse_error(String::from("String"))),
142 }
143 }
144
145 pub fn try_get_bool(&self) -> Result<bool, StdError> {
146 match self {
147 Primitive::Bool(value) => Ok(*value),
148 _ => Err(parse_error(String::from("bool"))),
149 }
150 }
151
152 pub fn try_get_vec(&self) -> Result<Vec<Primitive>, StdError> {
153 match self {
154 Primitive::Vec(vector) => Ok(vector.to_vec()),
155 _ => Err(parse_error(String::from("Vec"))),
156 }
157 }
158
159 pub fn try_get_coin(&self) -> Result<Coin, StdError> {
160 match self {
161 Primitive::Coin(coin) => Ok(coin.clone()),
162 _ => Err(parse_error(String::from("Coin"))),
163 }
164 }
165
166 pub fn try_get_addr(&self) -> Result<Addr, StdError> {
167 match self {
168 Primitive::Addr(addr) => Ok(addr.clone()),
169 _ => Err(parse_error(String::from("Addr"))),
170 }
171 }
172
173 pub fn try_get_binary(&self) -> Result<Binary, StdError> {
174 match self {
175 Primitive::Binary(value) => Ok(value.clone()),
176 _ => Err(parse_error(String::from("Binary"))),
177 }
178 }
179
180 pub fn try_get_object(&self) -> Result<Map<String, Primitive>, StdError> {
181 match self {
182 Primitive::Object(value) => Ok(value.clone()),
183 _ => Err(parse_error(String::from("Binary"))),
184 }
185 }
186}
187
188#[cw_serde]
189pub struct GetValueResponse {
190 pub key: String,
191 pub value: Primitive,
192}
193
194#[cfg(test)]
195mod tests {
196 use super::*;
197 use cosmwasm_std::to_json_binary;
198
199 #[test]
200 fn test_parse_error() {
201 assert_eq!(
202 StdError::ParseErr {
203 target_type: "target_type".to_string(),
204 msg: "Primitive is not a target_type".to_string()
205 },
206 parse_error("target_type".to_string())
207 );
208 }
209
210 #[test]
211 fn try_get_uint128() {
212 let primitive = Primitive::Uint128(Uint128::from(5_u128));
213 assert_eq!(Uint128::from(5_u128), primitive.try_get_uint128().unwrap());
214
215 let primitive = Primitive::Bool(true);
216 assert_eq!(
217 parse_error("Uint128".to_string()),
218 primitive.try_get_uint128().unwrap_err()
219 );
220 }
221
222 #[test]
223 fn try_get_string() {
224 let primitive = Primitive::String("String".to_string());
225 assert_eq!("String".to_string(), primitive.try_get_string().unwrap());
226
227 let primitive = Primitive::Bool(true);
228 assert_eq!(
229 parse_error("String".to_string()),
230 primitive.try_get_string().unwrap_err()
231 );
232 }
233
234 #[test]
235 fn try_get_bool() {
236 let primitive = Primitive::Bool(true);
237 assert!(primitive.try_get_bool().unwrap());
238
239 let primitive = Primitive::String("String".to_string());
240 assert_eq!(
241 parse_error("bool".to_string()),
242 primitive.try_get_bool().unwrap_err()
243 );
244 }
245
246 #[test]
247 fn try_get_vec() {
248 let primitive = Primitive::Vec(vec![Primitive::Bool(true)]);
249 assert_eq!(
250 vec![Primitive::Bool(true)],
251 primitive.try_get_vec().unwrap()
252 );
253
254 let primitive = Primitive::Vec(vec![Primitive::Vec(vec![Primitive::Bool(true)])]);
255 assert_eq!(
256 vec![Primitive::Vec(vec![Primitive::Bool(true)])],
257 primitive.try_get_vec().unwrap()
258 );
259
260 let primitive = Primitive::String("String".to_string());
261 assert_eq!(
262 parse_error("Vec".to_string()),
263 primitive.try_get_vec().unwrap_err()
264 );
265 }
266
267 #[test]
268 fn try_get_decimal() {
269 let primitive = Primitive::Decimal(Decimal::zero());
270 assert_eq!(Decimal::zero(), primitive.try_get_decimal().unwrap());
271
272 let primitive = Primitive::String("String".to_string());
273 assert_eq!(
274 parse_error("Decimal".to_string()),
275 primitive.try_get_decimal().unwrap_err()
276 );
277 }
278
279 #[test]
280 fn try_get_binary() {
281 let primitive = Primitive::Binary(to_json_binary("data").unwrap());
282 assert_eq!(
283 to_json_binary("data").unwrap(),
284 primitive.try_get_binary().unwrap()
285 );
286
287 let primitive = Primitive::String("String".to_string());
288 assert_eq!(
289 parse_error("Binary".to_string()),
290 primitive.try_get_binary().unwrap_err()
291 );
292 }
293
294 #[test]
295 fn try_get_object() {
296 let mut map = Map::new();
297 map.insert("key".to_string(), Primitive::Bool(true));
298 let primitive = Primitive::Object(map.clone());
299 assert_eq!(map.clone(), primitive.try_get_object().unwrap());
300 }
301}