14
14
15
15
use crate :: {
16
16
traits:: { FinalizeStoreTrait , RegistersLoad , RegistersStore , StackMatches , StackProgram } ,
17
+ CallOperator ,
17
18
Opcode ,
18
19
Operand ,
19
20
} ;
20
21
use console:: {
21
22
network:: prelude:: * ,
22
- program:: { Identifier , Literal , Register , Value } ,
23
+ program:: { Literal , Register , Value } ,
23
24
types:: Boolean ,
24
25
} ;
25
26
@@ -28,7 +29,7 @@ use console::{
28
29
#[ derive( Clone , PartialEq , Eq , Hash ) ]
29
30
pub struct Contains < N : Network > {
30
31
/// The mapping name.
31
- mapping : Identifier < N > ,
32
+ mapping : CallOperator < N > ,
32
33
/// The key to access the mapping.
33
34
key : Operand < N > ,
34
35
/// The destination register.
@@ -48,9 +49,9 @@ impl<N: Network> Contains<N> {
48
49
vec ! [ self . key. clone( ) ]
49
50
}
50
51
51
- /// Returns the mapping name .
52
+ /// Returns the mapping.
52
53
#[ inline]
53
- pub const fn mapping_name ( & self ) -> & Identifier < N > {
54
+ pub const fn mapping ( & self ) -> & CallOperator < N > {
54
55
& self . mapping
55
56
}
56
57
@@ -76,16 +77,22 @@ impl<N: Network> Contains<N> {
76
77
store : & impl FinalizeStoreTrait < N > ,
77
78
registers : & mut ( impl RegistersLoad < N > + RegistersStore < N > ) ,
78
79
) -> Result < ( ) > {
80
+ // Determine the program ID and mapping name.
81
+ let ( program_id, mapping_name) = match self . mapping {
82
+ CallOperator :: Locator ( locator) => ( * locator. program_id ( ) , * locator. resource ( ) ) ,
83
+ CallOperator :: Resource ( mapping_name) => ( * stack. program_id ( ) , mapping_name) ,
84
+ } ;
85
+
79
86
// Ensure the mapping exists in storage.
80
- if !store. contains_mapping_confirmed ( stack . program_id ( ) , & self . mapping ) ? {
81
- bail ! ( "Mapping '{}/{}' does not exist in storage" , stack . program_id ( ) , self . mapping ) ;
87
+ if !store. contains_mapping_confirmed ( & program_id, & mapping_name ) ? {
88
+ bail ! ( "Mapping '{program_id }/{mapping_name }' does not exist in storage" ) ;
82
89
}
83
90
84
91
// Load the operand as a plaintext.
85
92
let key = registers. load_plaintext ( stack, & self . key ) ?;
86
93
87
94
// Determine if the key exists in the mapping.
88
- let contains_key = store. contains_key_speculative ( * stack . program_id ( ) , self . mapping , & key) ?;
95
+ let contains_key = store. contains_key_speculative ( program_id, mapping_name , & key) ?;
89
96
90
97
// Assign the value to the destination register.
91
98
registers. store ( stack, & self . destination , Value :: from ( Literal :: Boolean ( Boolean :: new ( contains_key) ) ) ) ?;
@@ -106,7 +113,7 @@ impl<N: Network> Parser for Contains<N> {
106
113
let ( string, _) = Sanitizer :: parse_whitespaces ( string) ?;
107
114
108
115
// Parse the mapping name from the string.
109
- let ( string, mapping) = Identifier :: parse ( string) ?;
116
+ let ( string, mapping) = CallOperator :: parse ( string) ?;
110
117
// Parse the "[" from the string.
111
118
let ( string, _) = tag ( "[" ) ( string) ?;
112
119
// Parse the whitespace from the string.
@@ -177,7 +184,7 @@ impl<N: Network> FromBytes for Contains<N> {
177
184
/// Reads the command from a buffer.
178
185
fn read_le < R : Read > ( mut reader : R ) -> IoResult < Self > {
179
186
// Read the mapping name.
180
- let mapping = Identifier :: read_le ( & mut reader) ?;
187
+ let mapping = CallOperator :: read_le ( & mut reader) ?;
181
188
// Read the key operand.
182
189
let key = Operand :: read_le ( & mut reader) ?;
183
190
// Read the destination register.
@@ -210,9 +217,26 @@ mod tests {
210
217
fn test_parse ( ) {
211
218
let ( string, contains) = Contains :: < CurrentNetwork > :: parse ( "contains account[r0] into r1;" ) . unwrap ( ) ;
212
219
assert ! ( string. is_empty( ) , "Parser did not consume all of the string: '{string}'" ) ;
213
- assert_eq ! ( contains. mapping, Identifier :: from_str( "account" ) . unwrap( ) ) ;
220
+ assert_eq ! ( contains. mapping, CallOperator :: from_str( "account" ) . unwrap( ) ) ;
221
+ assert_eq ! ( contains. operands( ) . len( ) , 1 , "The number of operands is incorrect" ) ;
222
+ assert_eq ! ( contains. key, Operand :: Register ( Register :: Locator ( 0 ) ) , "The first operand is incorrect" ) ;
223
+ assert_eq ! ( contains. destination, Register :: Locator ( 1 ) , "The second operand is incorrect" ) ;
224
+
225
+ let ( string, contains) =
226
+ Contains :: < CurrentNetwork > :: parse ( "contains credits.aleo/account[r0] into r1;" ) . unwrap ( ) ;
227
+ assert ! ( string. is_empty( ) , "Parser did not consume all of the string: '{string}'" ) ;
228
+ assert_eq ! ( contains. mapping, CallOperator :: from_str( "credits.aleo/account" ) . unwrap( ) ) ;
214
229
assert_eq ! ( contains. operands( ) . len( ) , 1 , "The number of operands is incorrect" ) ;
215
230
assert_eq ! ( contains. key, Operand :: Register ( Register :: Locator ( 0 ) ) , "The first operand is incorrect" ) ;
216
231
assert_eq ! ( contains. destination, Register :: Locator ( 1 ) , "The second operand is incorrect" ) ;
217
232
}
233
+
234
+ #[ test]
235
+ fn test_from_bytes ( ) {
236
+ let ( string, contains) = Contains :: < CurrentNetwork > :: parse ( "contains account[r0] into r1;" ) . unwrap ( ) ;
237
+ assert ! ( string. is_empty( ) ) ;
238
+ let bytes_le = contains. to_bytes_le ( ) . unwrap ( ) ;
239
+ let result = Contains :: < CurrentNetwork > :: from_bytes_le ( & bytes_le[ ..] ) ;
240
+ assert ! ( result. is_ok( ) )
241
+ }
218
242
}
0 commit comments