multiversx_sc_scenario/scenario/model/value/
address_value.rs

1use multiversx_sc::{
2    api::ManagedTypeApi,
3    chain_core::std::Bech32Address,
4    types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom, TxFromSpecified},
5};
6use std::fmt;
7
8use crate::multiversx_sc::types::{Address, TestAddress, TestSCAddress};
9
10use crate::scenario_format::{
11    interpret_trait::{InterpretableFrom, InterpreterContext, IntoRaw},
12    serde_raw::ValueSubTree,
13    value_interpreter::{interpret_string, interpret_subtree},
14};
15
16use super::AddressKey;
17
18#[derive(PartialEq, Eq, Clone, Debug)]
19pub struct AddressValue {
20    pub value: Address,
21    pub original: ValueSubTree,
22}
23
24impl Default for AddressValue {
25    fn default() -> Self {
26        Self {
27            value: Address::zero(),
28            original: Default::default(),
29        }
30    }
31}
32
33impl AddressValue {
34    pub fn to_address(&self) -> Address {
35        self.value.clone()
36    }
37}
38
39impl fmt::Display for AddressValue {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        self.original.fmt(f)
42    }
43}
44
45pub(crate) fn value_from_slice(slice: &[u8]) -> Address {
46    let mut value = [0u8; 32];
47    if slice.len() == 32 {
48        value.copy_from_slice(slice);
49    } else {
50        panic!("account address is not 32 bytes in length");
51    }
52    value.into()
53}
54
55impl InterpretableFrom<ValueSubTree> for AddressValue {
56    fn interpret_from(from: ValueSubTree, context: &InterpreterContext) -> Self {
57        let bytes = interpret_subtree(&from, context);
58        AddressValue {
59            value: value_from_slice(bytes.as_slice()),
60            original: from,
61        }
62    }
63}
64
65impl InterpretableFrom<&str> for AddressValue {
66    fn interpret_from(from: &str, context: &InterpreterContext) -> Self {
67        let bytes = interpret_string(from, context);
68        AddressValue {
69            value: value_from_slice(bytes.as_slice()),
70            original: ValueSubTree::Str(from.to_string()),
71        }
72    }
73}
74
75impl IntoRaw<ValueSubTree> for AddressValue {
76    fn into_raw(self) -> ValueSubTree {
77        self.original
78    }
79}
80
81impl From<&AddressValue> for AddressValue {
82    fn from(from: &AddressValue) -> Self {
83        from.clone()
84    }
85}
86
87impl From<&AddressKey> for AddressValue {
88    fn from(from: &AddressKey) -> Self {
89        AddressValue {
90            value: from.to_address(),
91            original: ValueSubTree::Str(from.original.clone()),
92        }
93    }
94}
95
96impl From<AddressKey> for AddressValue {
97    fn from(from: AddressKey) -> Self {
98        AddressValue::from(&from)
99    }
100}
101
102impl From<&Address> for AddressValue {
103    fn from(from: &Address) -> Self {
104        AddressValue {
105            value: from.clone(),
106            original: ValueSubTree::Str(format!("0x{}", hex::encode(from))),
107        }
108    }
109}
110
111impl From<&Bech32Address> for AddressValue {
112    fn from(from: &Bech32Address) -> Self {
113        AddressValue {
114            value: from.to_address().clone(),
115            original: ValueSubTree::Str(from.to_bech32_expr()),
116        }
117    }
118}
119
120impl From<Bech32Address> for AddressValue {
121    fn from(from: Bech32Address) -> Self {
122        AddressValue {
123            original: ValueSubTree::Str(from.to_bech32_expr()),
124            value: from.into_address(),
125        }
126    }
127}
128
129impl From<&str> for AddressValue {
130    fn from(from: &str) -> Self {
131        AddressValue::interpret_from(from, &InterpreterContext::default())
132    }
133}
134
135impl From<TestAddress<'_>> for AddressValue {
136    fn from(from: TestAddress) -> Self {
137        AddressValue {
138            value: from.eval_to_array().into(),
139            original: ValueSubTree::Str(from.eval_to_expr()),
140        }
141    }
142}
143
144impl From<TestSCAddress<'_>> for AddressValue {
145    fn from(from: TestSCAddress) -> Self {
146        AddressValue {
147            value: from.eval_to_array().into(),
148            original: ValueSubTree::Str(from.eval_to_expr()),
149        }
150    }
151}
152
153impl<M> From<&AddressValue> for ManagedAddress<M>
154where
155    M: ManagedTypeApi,
156{
157    #[inline]
158    fn from(address_value: &AddressValue) -> Self {
159        ManagedAddress::from_address(&address_value.value)
160    }
161}
162
163impl<Env> TxFrom<Env> for AddressValue
164where
165    Env: TxEnv,
166{
167    fn resolve_address(&self, _env: &Env) -> ManagedAddress<Env::Api> {
168        self.into()
169    }
170}
171
172impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for AddressValue
173where
174    Env: TxEnv,
175{
176    fn annotation(&self, _env: &Env) -> multiversx_sc::types::ManagedBuffer<Env::Api> {
177        ManagedBuffer::from(self.original.to_string())
178    }
179
180    fn to_value(&self, _env: &Env) -> ManagedAddress<Env::Api> {
181        ManagedAddress::from_address(&self.value)
182    }
183
184    fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
185        ManagedAddress::from_address(&self.value)
186    }
187
188    fn with_value_ref<F, R>(&self, _env: &Env, f: F) -> R
189    where
190        F: FnOnce(&ManagedAddress<Env::Api>) -> R,
191    {
192        f(&ManagedAddress::from_address(&self.value))
193    }
194}
195
196impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for &AddressValue
197where
198    Env: TxEnv,
199{
200    fn annotation(&self, _env: &Env) -> multiversx_sc::types::ManagedBuffer<Env::Api> {
201        ManagedBuffer::from(self.original.to_string())
202    }
203
204    fn to_value(&self, _env: &Env) -> ManagedAddress<Env::Api> {
205        ManagedAddress::from_address(&self.value)
206    }
207
208    fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
209        ManagedAddress::from_address(&self.value)
210    }
211
212    fn with_value_ref<F, R>(&self, _env: &Env, f: F) -> R
213    where
214        F: FnOnce(&ManagedAddress<Env::Api>) -> R,
215    {
216        f(&ManagedAddress::from_address(&self.value))
217    }
218}
219
220impl<Env> TxFromSpecified<Env> for AddressValue where Env: TxEnv {}
221
222impl<Env> TxFrom<Env> for &AddressValue
223where
224    Env: TxEnv,
225{
226    fn resolve_address(&self, _env: &Env) -> ManagedAddress<Env::Api> {
227        ManagedAddress::from_address(&self.value)
228    }
229}
230
231impl<Env> TxFromSpecified<Env> for &AddressValue where Env: TxEnv {}