multiversx_sc_scenario/scenario/model/value/
value_check.rs

1use crate::scenario_format::{
2    interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw},
3    serde_raw::{CheckBytesValueRaw, CheckValueListRaw, ValueSubTree},
4};
5
6use std::{fmt, fmt::Write};
7
8use super::BytesValue;
9
10#[derive(Debug, Clone, Default)]
11pub enum CheckValue<T: Default> {
12    #[default]
13    Star,
14    Equal(T),
15}
16
17impl<T> CheckValue<T>
18where
19    T: InterpretableFrom<ValueSubTree> + Default,
20{
21    pub fn is_star(&self) -> bool {
22        matches!(self, CheckValue::Star)
23    }
24
25    pub fn is_equal_to(&self, _value: T) -> bool {
26        matches!(self, CheckValue::Equal(_value))
27    }
28}
29
30impl<T> InterpretableFrom<CheckBytesValueRaw> for CheckValue<T>
31where
32    T: InterpretableFrom<ValueSubTree> + Default,
33{
34    fn interpret_from(from: CheckBytesValueRaw, context: &InterpreterContext) -> Self {
35        match from {
36            CheckBytesValueRaw::Unspecified => CheckValue::Star,
37            CheckBytesValueRaw::Star => CheckValue::Star,
38            CheckBytesValueRaw::Equal(bytes_value) => {
39                CheckValue::Equal(T::interpret_from(bytes_value, context))
40            }
41        }
42    }
43}
44
45impl<T> IntoRaw<CheckBytesValueRaw> for CheckValue<T>
46where
47    T: IntoRaw<ValueSubTree> + Default,
48{
49    fn into_raw(self) -> CheckBytesValueRaw {
50        match self {
51            CheckValue::Star => CheckBytesValueRaw::Unspecified,
52            CheckValue::Equal(eq) => CheckBytesValueRaw::Equal(eq.into_raw()),
53        }
54    }
55}
56
57impl<T> CheckValue<T>
58where
59    T: IntoRaw<ValueSubTree> + Default,
60{
61    pub fn into_raw_explicit(self) -> CheckBytesValueRaw {
62        match self {
63            CheckValue::Star => CheckBytesValueRaw::Star,
64            CheckValue::Equal(eq) => CheckBytesValueRaw::Equal(eq.into_raw()),
65        }
66    }
67}
68
69impl<T: fmt::Display + Default> fmt::Display for CheckValue<T> {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        match self {
72            CheckValue::Star => write!(f, "*"),
73            CheckValue::Equal(eq_value) => eq_value.fmt(f),
74        }
75    }
76}
77
78/// Alias for a list of item checks that can be ignored altogether.
79/// Valid values (with different behaviors): `"*"`, `["*"]`, `["1", "*"]`, `["*", "*", "*"]`
80pub type CheckValueList = CheckValue<Vec<CheckValue<BytesValue>>>;
81
82impl InterpretableFrom<CheckValueListRaw> for CheckValueList {
83    fn interpret_from(from: CheckValueListRaw, context: &InterpreterContext) -> Self {
84        match from {
85            CheckValueListRaw::Unspecified => CheckValue::Star,
86            CheckValueListRaw::Star => CheckValue::Star,
87            CheckValueListRaw::CheckList(list_raw) => CheckValue::Equal(
88                list_raw
89                    .into_iter()
90                    .map(|check_raw| CheckValue::<BytesValue>::interpret_from(check_raw, context))
91                    .collect(),
92            ),
93        }
94    }
95}
96
97impl IntoRaw<CheckValueListRaw> for CheckValueList {
98    fn into_raw(self) -> CheckValueListRaw {
99        match self {
100            CheckValue::Star => CheckValueListRaw::Unspecified,
101            CheckValue::Equal(list) => CheckValueListRaw::CheckList(
102                list.into_iter().map(|cv| cv.into_raw_explicit()).collect(),
103            ),
104        }
105    }
106}
107
108impl CheckValue<BytesValue> {
109    pub fn pretty_str(&self) -> String {
110        match self {
111            CheckValue::Star => "*".to_string(),
112            CheckValue::Equal(value) => String::from_utf8_lossy(&value.value).into_owned(),
113        }
114    }
115}
116
117impl CheckValueList {
118    pub fn pretty_str(&self) -> String {
119        match self {
120            CheckValue::Star => "*".to_string(),
121            CheckValue::Equal(list) => {
122                let mut s = String::new();
123                s.push('[');
124                for (i, check_value) in list.iter().enumerate() {
125                    if i > 0 {
126                        s.push(',');
127                    }
128                    write!(s, "{check_value}").unwrap();
129                }
130                s.push(']');
131                s
132            }
133        }
134    }
135}