multiversx_sc/types/interaction/expr/
test_address.rs1use core::ptr;
2
3use multiversx_sc_codec::{
4 EncodeErrorHandler, NestedEncode, NestedEncodeOutput, TopEncode, TopEncodeOutput,
5};
6
7use crate::{
8 abi::TypeAbiFrom,
9 api::ManagedTypeApi,
10 types::{
11 heap::Address, AnnotatedValue, ManagedAddress, ManagedBuffer, TxEnv, TxFrom,
12 TxFromSpecified, TxTo, TxToSpecified,
13 },
14};
15
16use super::TestSCAddress;
17
18const ADDRESS_PREFIX: &str = "address:";
19
20#[derive(Clone, Copy, Debug, PartialEq, Eq)]
25pub struct TestAddress<'a> {
26 name: &'a str,
27}
28
29impl<'a> TestAddress<'a> {
30 pub const fn new(name: &'a str) -> Self {
31 TestAddress { name }
32 }
33
34 pub fn eval_to_array(&self) -> [u8; 32] {
35 let result = [b'_'; 32];
36 let expr_bytes = self.name.as_bytes();
37 let mut len = expr_bytes.len();
38 if len > 32 {
39 len = 32;
40 }
41 unsafe {
42 ptr::copy_nonoverlapping(expr_bytes.as_ptr(), result.as_ptr() as *mut u8, len);
43 }
44 result
45 }
46
47 pub fn to_address(&self) -> Address {
48 self.eval_to_array().into()
49 }
50
51 pub fn to_managed_address<Api: ManagedTypeApi>(&self) -> ManagedAddress<Api> {
52 self.eval_to_array().into()
53 }
54
55 #[cfg(feature = "alloc")]
56 pub fn eval_to_expr(&self) -> alloc::string::String {
57 alloc::format!("{ADDRESS_PREFIX}{}", self.name)
58 }
59}
60
61impl PartialEq<TestSCAddress<'_>> for TestAddress<'_> {
62 fn eq(&self, other: &TestSCAddress) -> bool {
63 self.to_address() == other.to_address()
64 }
65}
66
67impl PartialEq<Address> for TestAddress<'_> {
68 fn eq(&self, other: &Address) -> bool {
69 &self.to_address() == other
70 }
71}
72
73impl<'a> PartialEq<TestAddress<'a>> for Address {
74 fn eq(&self, other: &TestAddress<'a>) -> bool {
75 self == &other.to_address()
76 }
77}
78
79impl<Api: ManagedTypeApi> PartialEq<ManagedAddress<Api>> for TestAddress<'_> {
80 fn eq(&self, other: &ManagedAddress<Api>) -> bool {
81 self.to_address() == other.to_address()
82 }
83}
84
85impl<'a, Api: ManagedTypeApi> PartialEq<TestAddress<'a>> for ManagedAddress<Api> {
86 fn eq(&self, other: &TestAddress<'a>) -> bool {
87 self.to_address() == other.to_address()
88 }
89}
90
91impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for TestAddress<'_>
92where
93 Env: TxEnv,
94{
95 fn annotation(&self, _env: &Env) -> ManagedBuffer<Env::Api> {
96 let mut result = ManagedBuffer::new_from_bytes(ADDRESS_PREFIX.as_bytes());
97 result.append_bytes(self.name.as_bytes());
98 result
99 }
100
101 fn to_value(&self, _env: &Env) -> ManagedAddress<Env::Api> {
102 let expr: [u8; 32] = self.eval_to_array();
103 expr.into()
104 }
105}
106
107impl<Env> TxFrom<Env> for TestAddress<'_>
108where
109 Env: TxEnv,
110{
111 fn resolve_address(&self, _env: &Env) -> ManagedAddress<Env::Api> {
112 let expr: [u8; 32] = self.eval_to_array();
113 expr.into()
114 }
115}
116impl<Env> TxFromSpecified<Env> for TestAddress<'_> where Env: TxEnv {}
117impl<Env> TxTo<Env> for TestAddress<'_> where Env: TxEnv {}
118impl<Env> TxToSpecified<Env> for TestAddress<'_> where Env: TxEnv {}
119
120impl TopEncode for TestAddress<'_> {
121 fn top_encode_or_handle_err<O, H>(&self, output: O, h: H) -> Result<(), H::HandledErr>
122 where
123 O: TopEncodeOutput,
124 H: EncodeErrorHandler,
125 {
126 self.eval_to_array().top_encode_or_handle_err(output, h)
127 }
128}
129
130impl NestedEncode for TestAddress<'_> {
131 #[inline]
132 fn dep_encode_or_handle_err<O, H>(&self, dest: &mut O, h: H) -> Result<(), H::HandledErr>
133 where
134 O: NestedEncodeOutput,
135 H: EncodeErrorHandler,
136 {
137 self.eval_to_array().dep_encode_or_handle_err(dest, h)
138 }
139}
140
141impl<Api> TypeAbiFrom<TestAddress<'_>> for ManagedAddress<Api> where Api: ManagedTypeApi {}
142
143#[cfg(test)]
144pub mod tests {
145 use super::*;
146
147 fn assert_eq_eval(expr: &'static str, expected: &[u8; 32]) {
148 assert_eq!(&TestAddress::new(expr).eval_to_array(), expected);
149 }
150
151 #[test]
152 fn test_address_value() {
153 assert_eq_eval("", b"________________________________");
154 assert_eq_eval("a", b"a_______________________________");
155 assert_eq_eval("a\x05", b"a\x05______________________________");
156 assert_eq_eval("an_address", b"an_address______________________");
157 assert_eq_eval(
158 "12345678901234567890123456789012",
159 b"12345678901234567890123456789012",
160 );
161 assert_eq_eval(
162 "123456789012345678901234567890123",
163 b"12345678901234567890123456789012",
164 );
165 }
166}