1use schemars::JsonSchema;
2use serde::{Deserialize, Serialize};
3
4use cosmwasm_std::{StdError, StdResult, Uint512};
5use serde_cw_value::Value;
6
7#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
8#[serde(rename_all = "snake_case")]
9pub enum ValueOrdering {
10 UnitAbove,
11 UnitAboveEqual,
12 UnitBelow,
13 UnitBelowEqual,
14 Equal,
15 NotEqual,
16}
17
18impl ValueOrdering {
19 pub fn val_cmp(&self, lhs: &Value, rhs: &Value) -> StdResult<bool> {
20 let res = match self {
21 ValueOrdering::UnitAbove => lhs.bt_g(rhs)?,
22 ValueOrdering::UnitAboveEqual => lhs.be_g(rhs)?,
23 ValueOrdering::UnitBelow => lhs.lt_g(rhs)?,
24 ValueOrdering::UnitBelowEqual => lhs.le_g(rhs)?,
25 ValueOrdering::Equal => lhs.eq(rhs),
26 ValueOrdering::NotEqual => lhs.ne(rhs),
27 };
28 Ok(res)
29 }
30}
31
32pub trait ValueOrd {
33 fn lt_g(&self, other: &Self) -> StdResult<bool>;
34 fn le_g(&self, other: &Self) -> StdResult<bool>;
35 fn bt_g(&self, other: &Self) -> StdResult<bool>;
36 fn be_g(&self, other: &Self) -> StdResult<bool>;
37 fn equal(&self, other: &Self) -> bool;
38}
39
40impl ValueOrd for Value {
42 fn lt_g(&self, other: &Self) -> StdResult<bool> {
43 match (self, other) {
44 (Value::String(str_num), Value::String(oth)) => {
45 let big_num: Uint512 = str_num.parse()?;
46 let big_oth: Uint512 = oth.parse()?;
47 Ok(big_num < big_oth)
48 }
49 (Value::U64(n), Value::U64(o)) => Ok(n < o),
50 (Value::U32(n), Value::U32(o)) => Ok(n < o),
51 (Value::U16(n), Value::U16(o)) => Ok(n < o),
52 (Value::U8(n), Value::U8(o)) => Ok(n < o),
53 _ => Err(StdError::parse_err(
54 "number",
55 "Failed to parse to Uint512 and to u64",
56 )),
57 }
58 }
59
60 fn le_g(&self, other: &Self) -> StdResult<bool> {
61 match (self, other) {
62 (Value::String(str_num), Value::String(oth)) => {
63 let big_num: Uint512 = str_num.parse()?;
64 let big_oth: Uint512 = oth.parse()?;
65 Ok(big_num <= big_oth)
66 }
67 (Value::U64(n), Value::U64(o)) => Ok(n <= o),
68 (Value::U32(n), Value::U32(o)) => Ok(n <= o),
69 (Value::U16(n), Value::U16(o)) => Ok(n <= o),
70 (Value::U8(n), Value::U8(o)) => Ok(n <= o),
71 _ => Err(StdError::parse_err(
72 "number",
73 "Failed to parse to Uint512 and to u64",
74 )),
75 }
76 }
77
78 fn bt_g(&self, other: &Self) -> StdResult<bool> {
79 match (self, other) {
80 (Value::String(str_num), Value::String(oth)) => {
81 let big_num: Uint512 = str_num.parse()?;
82 let big_oth: Uint512 = oth.parse()?;
83 Ok(big_num > big_oth)
84 }
85 (Value::U64(n), Value::U64(o)) => Ok(n > o),
86 (Value::U32(n), Value::U32(o)) => Ok(n > o),
87 (Value::U16(n), Value::U16(o)) => Ok(n > o),
88 (Value::U8(n), Value::U8(o)) => Ok(n > o),
89 _ => Err(StdError::parse_err(
90 "number",
91 "Failed to parse to Uint512 and to u64",
92 )),
93 }
94 }
95
96 fn be_g(&self, other: &Self) -> StdResult<bool> {
97 match (self, other) {
98 (Value::String(str_num), Value::String(oth)) => {
99 let big_num: Uint512 = str_num.parse()?;
100 let big_oth: Uint512 = oth.parse()?;
101 Ok(big_num >= big_oth)
102 }
103 (Value::U64(n), Value::U64(o)) => Ok(n >= o),
104 (Value::U32(n), Value::U32(o)) => Ok(n >= o),
105 (Value::U16(n), Value::U16(o)) => Ok(n >= o),
106 (Value::U8(n), Value::U8(o)) => Ok(n >= o),
107 _ => Err(StdError::parse_err(
108 "number",
109 "Failed to parse to Uint512 and to u64",
110 )),
111 }
112 }
113
114 fn equal(&self, other: &Self) -> bool {
115 self.eq(other)
116 }
117}
118
119#[cfg(test)]
120mod test {
121 use cosmwasm_std::StdError;
122
123 use super::ValueOrd;
124
125 #[test]
126 fn test_lt_g() {
127 assert!(serde_cw_value::to_value(5_u64)
129 .unwrap()
130 .lt_g(&serde_cw_value::to_value(6_u64).unwrap())
131 .unwrap());
132 assert!(serde_cw_value::to_value("5")
133 .unwrap()
134 .lt_g(&serde_cw_value::to_value("6").unwrap())
135 .unwrap());
136 assert!(!serde_cw_value::to_value(5_u64)
138 .unwrap()
139 .lt_g(&serde_cw_value::to_value(5_u64).unwrap())
140 .unwrap());
141 assert!(!serde_cw_value::to_value("5")
142 .unwrap()
143 .lt_g(&serde_cw_value::to_value("5").unwrap())
144 .unwrap());
145 assert!(!serde_cw_value::to_value(42_u64)
147 .unwrap()
148 .lt_g(&serde_cw_value::to_value(8_u64).unwrap())
149 .unwrap());
150 assert!(!serde_cw_value::to_value("42")
151 .unwrap()
152 .lt_g(&serde_cw_value::to_value("8").unwrap())
153 .unwrap());
154 }
155
156 #[test]
157 fn test_lt_negative() {
158 let different_types = serde_cw_value::to_value(5_u64)
159 .unwrap()
160 .lt_g(&serde_cw_value::to_value("6").unwrap())
161 .unwrap_err();
162 assert!(matches!(different_types, StdError::ParseErr { .. }));
163
164 let different_types = serde_cw_value::to_value("5")
165 .unwrap()
166 .lt_g(&serde_cw_value::to_value(6_u64).unwrap())
167 .unwrap_err();
168 assert!(matches!(different_types, StdError::ParseErr { .. }));
169
170 let invalid_value = serde_cw_value::to_value("foo")
171 .unwrap()
172 .lt_g(&serde_cw_value::to_value(6_u64).unwrap())
173 .unwrap_err();
174 assert!(matches!(invalid_value, StdError::ParseErr { .. }));
175
176 let invalid_value = serde_cw_value::to_value("5")
177 .unwrap()
178 .lt_g(&serde_cw_value::to_value("bar").unwrap())
179 .unwrap_err();
180 assert!(matches!(invalid_value, StdError::GenericErr { .. }));
181 }
182
183 #[test]
184 fn test_le_g() {
185 assert!(serde_cw_value::to_value(5_u64)
187 .unwrap()
188 .le_g(&serde_cw_value::to_value(6_u64).unwrap())
189 .unwrap());
190 assert!(serde_cw_value::to_value("5")
191 .unwrap()
192 .le_g(&serde_cw_value::to_value("6").unwrap())
193 .unwrap());
194 assert!(serde_cw_value::to_value(5_u64)
196 .unwrap()
197 .le_g(&serde_cw_value::to_value(5_u64).unwrap())
198 .unwrap());
199 assert!(serde_cw_value::to_value("5")
200 .unwrap()
201 .le_g(&serde_cw_value::to_value("5").unwrap())
202 .unwrap());
203 assert!(!serde_cw_value::to_value(42_u64)
205 .unwrap()
206 .le_g(&serde_cw_value::to_value(8_u64).unwrap())
207 .unwrap());
208 assert!(!serde_cw_value::to_value("42")
209 .unwrap()
210 .le_g(&serde_cw_value::to_value("8").unwrap())
211 .unwrap());
212 }
213
214 #[test]
215 fn test_le_negative() {
216 let different_types = serde_cw_value::to_value(5_u64)
217 .unwrap()
218 .le_g(&serde_cw_value::to_value("6").unwrap())
219 .unwrap_err();
220 assert!(matches!(different_types, StdError::ParseErr { .. }));
221
222 let different_types = serde_cw_value::to_value("5")
223 .unwrap()
224 .le_g(&serde_cw_value::to_value(6_u64).unwrap())
225 .unwrap_err();
226 assert!(matches!(different_types, StdError::ParseErr { .. }));
227
228 let invalid_value = serde_cw_value::to_value("foo")
229 .unwrap()
230 .le_g(&serde_cw_value::to_value(6_u64).unwrap())
231 .unwrap_err();
232 assert!(matches!(invalid_value, StdError::ParseErr { .. }));
233
234 let invalid_value = serde_cw_value::to_value("5")
235 .unwrap()
236 .le_g(&serde_cw_value::to_value("bar").unwrap())
237 .unwrap_err();
238 assert!(matches!(invalid_value, StdError::GenericErr { .. }));
239 }
240
241 #[test]
242 fn test_bt_g() {
243 assert!(!serde_cw_value::to_value(5_u64)
245 .unwrap()
246 .bt_g(&serde_cw_value::to_value(6_u64).unwrap())
247 .unwrap());
248 assert!(!serde_cw_value::to_value("5")
249 .unwrap()
250 .bt_g(&serde_cw_value::to_value("6").unwrap())
251 .unwrap());
252 assert!(!serde_cw_value::to_value(5_u64)
254 .unwrap()
255 .bt_g(&serde_cw_value::to_value(5_u64).unwrap())
256 .unwrap());
257 assert!(!serde_cw_value::to_value("5")
258 .unwrap()
259 .bt_g(&serde_cw_value::to_value("5").unwrap())
260 .unwrap());
261 assert!(serde_cw_value::to_value(42_u64)
263 .unwrap()
264 .bt_g(&serde_cw_value::to_value(8_u64).unwrap())
265 .unwrap());
266 assert!(serde_cw_value::to_value("42")
267 .unwrap()
268 .bt_g(&serde_cw_value::to_value("8").unwrap())
269 .unwrap());
270 }
271
272 #[test]
273 fn test_bt_negative() {
274 let different_types = serde_cw_value::to_value(5_u64)
275 .unwrap()
276 .bt_g(&serde_cw_value::to_value("6").unwrap())
277 .unwrap_err();
278 assert!(matches!(different_types, StdError::ParseErr { .. }));
279
280 let different_types = serde_cw_value::to_value("5")
281 .unwrap()
282 .bt_g(&serde_cw_value::to_value(6_u64).unwrap())
283 .unwrap_err();
284 assert!(matches!(different_types, StdError::ParseErr { .. }));
285
286 let invalid_value = serde_cw_value::to_value("foo")
287 .unwrap()
288 .bt_g(&serde_cw_value::to_value(6_u64).unwrap())
289 .unwrap_err();
290 assert!(matches!(invalid_value, StdError::ParseErr { .. }));
291
292 let invalid_value = serde_cw_value::to_value("5")
293 .unwrap()
294 .bt_g(&serde_cw_value::to_value("bar").unwrap())
295 .unwrap_err();
296 assert!(matches!(invalid_value, StdError::GenericErr { .. }));
297 }
298
299 #[test]
300 fn test_be_g() {
301 assert!(!serde_cw_value::to_value(5_u64)
303 .unwrap()
304 .be_g(&serde_cw_value::to_value(6_u64).unwrap())
305 .unwrap());
306 assert!(!serde_cw_value::to_value("5")
307 .unwrap()
308 .be_g(&serde_cw_value::to_value("6").unwrap())
309 .unwrap());
310 assert!(serde_cw_value::to_value(5_u64)
312 .unwrap()
313 .be_g(&serde_cw_value::to_value(5_u64).unwrap())
314 .unwrap());
315 assert!(serde_cw_value::to_value("5")
316 .unwrap()
317 .be_g(&serde_cw_value::to_value("5").unwrap())
318 .unwrap());
319 assert!(serde_cw_value::to_value(42_u64)
321 .unwrap()
322 .be_g(&serde_cw_value::to_value(8_u64).unwrap())
323 .unwrap());
324 assert!(serde_cw_value::to_value("42")
325 .unwrap()
326 .be_g(&serde_cw_value::to_value("8").unwrap())
327 .unwrap());
328 }
329
330 #[test]
331 fn test_be_negative() {
332 let different_types = serde_cw_value::to_value(5_u64)
333 .unwrap()
334 .be_g(&serde_cw_value::to_value("6").unwrap())
335 .unwrap_err();
336 assert!(matches!(different_types, StdError::ParseErr { .. }));
337
338 let different_types = serde_cw_value::to_value("5")
339 .unwrap()
340 .be_g(&serde_cw_value::to_value(6_u64).unwrap())
341 .unwrap_err();
342 assert!(matches!(different_types, StdError::ParseErr { .. }));
343
344 let invalid_value = serde_cw_value::to_value("foo")
345 .unwrap()
346 .be_g(&serde_cw_value::to_value(6_u64).unwrap())
347 .unwrap_err();
348 assert!(matches!(invalid_value, StdError::ParseErr { .. }));
349
350 let invalid_value = serde_cw_value::to_value("5")
351 .unwrap()
352 .be_g(&serde_cw_value::to_value("bar").unwrap())
353 .unwrap_err();
354 assert!(matches!(invalid_value, StdError::GenericErr { .. }));
355 }
356
357 #[test]
358 fn test_equal() {
359 assert!(!serde_cw_value::to_value(5_u64)
361 .unwrap()
362 .equal(&serde_cw_value::to_value(6_u64).unwrap()));
363 assert!(!serde_cw_value::to_value("5")
364 .unwrap()
365 .equal(&serde_cw_value::to_value("6").unwrap()));
366 assert!(serde_cw_value::to_value(5_u64)
368 .unwrap()
369 .equal(&serde_cw_value::to_value(5_u64).unwrap()));
370 assert!(serde_cw_value::to_value("5")
371 .unwrap()
372 .equal(&serde_cw_value::to_value("5").unwrap()));
373 assert!(!serde_cw_value::to_value(42_u64)
375 .unwrap()
376 .equal(&serde_cw_value::to_value(8_u64).unwrap()));
377 assert!(!serde_cw_value::to_value("42")
378 .unwrap()
379 .equal(&serde_cw_value::to_value("8").unwrap()));
380
381 assert!(serde_cw_value::to_value(r#"{"foo": "bar"}"#)
383 .unwrap()
384 .equal(&serde_cw_value::to_value(r#"{"foo": "bar"}"#).unwrap()));
385 assert!(!serde_cw_value::to_value(r#"{"foo": "bar"}"#)
386 .unwrap()
387 .equal(&serde_cw_value::to_value(r#"{"bar": "foo"}"#).unwrap()));
388 }
389}