/ console / program / src / data / register / mod.rs
mod.rs
  1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
  2  // This file is part of the alphavm library.
  3  
  4  // Licensed under the Apache License, Version 2.0 (the "License");
  5  // you may not use this file except in compliance with the License.
  6  // You may obtain a copy of the License at:
  7  
  8  // http://www.apache.org/licenses/LICENSE-2.0
  9  
 10  // Unless required by applicable law or agreed to in writing, software
 11  // distributed under the License is distributed on an "AS IS" BASIS,
 12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  // See the License for the specific language governing permissions and
 14  // limitations under the License.
 15  
 16  mod bytes;
 17  mod parse;
 18  mod serialize;
 19  
 20  use crate::Access;
 21  use alphavm_console_network::prelude::*;
 22  
 23  /// A register contains the location data to a value in memory.
 24  #[derive(Clone, PartialEq, Eq, Hash)]
 25  pub enum Register<N: Network> {
 26      /// A register contains its locator in memory.
 27      Locator(u64),
 28      /// A register access contains its locator and access(es) in memory.
 29      Access(u64, Vec<Access<N>>),
 30  }
 31  
 32  impl<N: Network> Register<N> {
 33      /// Returns the locator of the register.
 34      #[inline]
 35      pub const fn locator(&self) -> u64 {
 36          match self {
 37              Self::Locator(locator) => *locator,
 38              Self::Access(locator, _) => *locator,
 39          }
 40      }
 41  }
 42  
 43  impl<N: Network> Ord for Register<N> {
 44      /// Ordering is determined by the register locator (any accesses are ignored).
 45      fn cmp(&self, other: &Self) -> Ordering {
 46          self.locator().cmp(&other.locator())
 47      }
 48  }
 49  
 50  impl<N: Network> PartialOrd for Register<N> {
 51      /// Ordering is determined by the register locator (any accesses are ignored).
 52      fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 53          Some(self.cmp(other))
 54      }
 55  }
 56  
 57  #[cfg(test)]
 58  mod tests {
 59      use super::*;
 60      use crate::{Identifier, U32};
 61      use alphavm_console_network::MainnetV0;
 62  
 63      type CurrentNetwork = MainnetV0;
 64  
 65      #[test]
 66      fn test_register_partial_ord() -> Result<()> {
 67          // Register::Locator
 68          assert_eq!(
 69              Some(Ordering::Equal),
 70              Register::<CurrentNetwork>::Locator(0).partial_cmp(&Register::<CurrentNetwork>::Locator(0))
 71          );
 72          assert_eq!(
 73              Some(Ordering::Less),
 74              Register::<CurrentNetwork>::Locator(0).partial_cmp(&Register::<CurrentNetwork>::Locator(1))
 75          );
 76          assert_eq!(
 77              Some(Ordering::Greater),
 78              Register::<CurrentNetwork>::Locator(1).partial_cmp(&Register::<CurrentNetwork>::Locator(0))
 79          );
 80  
 81          // Register::Access with Access::Member
 82          assert_eq!(
 83              Some(Ordering::Equal),
 84              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]).partial_cmp(
 85                  &Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)])
 86              )
 87          );
 88          assert_eq!(
 89              Some(Ordering::Less),
 90              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]).partial_cmp(
 91                  &Register::<CurrentNetwork>::Access(1, vec![Access::Member(Identifier::from_str("owner")?)])
 92              )
 93          );
 94          assert_eq!(
 95              Some(Ordering::Greater),
 96              Register::<CurrentNetwork>::Access(1, vec![Access::Member(Identifier::from_str("owner")?)]).partial_cmp(
 97                  &Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)])
 98              )
 99          );
100  
101          // Register::Access with Access::Index
102          assert_eq!(
103              Some(Ordering::Equal),
104              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]).partial_cmp(&Register::<
105                  CurrentNetwork,
106              >::Access(
107                  0,
108                  vec![Access::Index(U32::new(0))]
109              ))
110          );
111          assert_eq!(
112              Some(Ordering::Less),
113              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]).partial_cmp(&Register::<
114                  CurrentNetwork,
115              >::Access(
116                  1,
117                  vec![Access::Index(U32::new(0))]
118              ))
119          );
120          assert_eq!(
121              Some(Ordering::Greater),
122              Register::<CurrentNetwork>::Access(1, vec![Access::Index(U32::new(0))]).partial_cmp(&Register::<
123                  CurrentNetwork,
124              >::Access(
125                  0,
126                  vec![Access::Index(U32::new(0))]
127              ))
128          );
129  
130          // Register::Access with a combination of Access::Member and Access::Index
131          assert_eq!(
132              Some(Ordering::Equal),
133              Register::<CurrentNetwork>::Access(0, vec![
134                  Access::Member(Identifier::from_str("owner")?),
135                  Access::Index(U32::new(0))
136              ])
137              .partial_cmp(&Register::<CurrentNetwork>::Access(0, vec![
138                  Access::Member(Identifier::from_str("owner")?),
139                  Access::Index(U32::new(0))
140              ]))
141          );
142          assert_eq!(
143              Some(Ordering::Less),
144              Register::<CurrentNetwork>::Access(0, vec![
145                  Access::Member(Identifier::from_str("owner")?),
146                  Access::Index(U32::new(0))
147              ])
148              .partial_cmp(&Register::<CurrentNetwork>::Access(1, vec![
149                  Access::Member(Identifier::from_str("owner")?),
150                  Access::Index(U32::new(0))
151              ]))
152          );
153          assert_eq!(
154              Some(Ordering::Greater),
155              Register::<CurrentNetwork>::Access(1, vec![
156                  Access::Member(Identifier::from_str("owner")?),
157                  Access::Index(U32::new(0))
158              ])
159              .partial_cmp(&Register::<CurrentNetwork>::Access(0, vec![
160                  Access::Member(Identifier::from_str("owner")?),
161                  Access::Index(U32::new(0))
162              ]))
163          );
164  
165          Ok(())
166      }
167  
168      #[test]
169      fn test_register_eq() -> Result<()> {
170          // Register::Locator
171          assert_eq!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(0));
172          assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(1));
173          assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(2));
174          assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(3));
175          assert_ne!(Register::<CurrentNetwork>::Locator(0), Register::<CurrentNetwork>::Locator(4));
176  
177          // Register::Access with Access::Member
178          assert_eq!(
179              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
180              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)])
181          );
182          assert_ne!(
183              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
184              Register::<CurrentNetwork>::Access(1, vec![Access::Member(Identifier::from_str("owner")?)])
185          );
186          assert_ne!(
187              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
188              Register::<CurrentNetwork>::Access(2, vec![Access::Member(Identifier::from_str("owner")?)])
189          );
190          assert_ne!(
191              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
192              Register::<CurrentNetwork>::Access(3, vec![Access::Member(Identifier::from_str("owner")?)])
193          );
194          assert_ne!(
195              Register::<CurrentNetwork>::Access(0, vec![Access::Member(Identifier::from_str("owner")?)]),
196              Register::<CurrentNetwork>::Access(4, vec![Access::Member(Identifier::from_str("owner")?)])
197          );
198  
199          // Register::Access with Access::Index
200          assert_eq!(
201              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
202              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))])
203          );
204          assert_ne!(
205              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
206              Register::<CurrentNetwork>::Access(1, vec![Access::Index(U32::new(0))])
207          );
208          assert_ne!(
209              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
210              Register::<CurrentNetwork>::Access(2, vec![Access::Index(U32::new(0))])
211          );
212          assert_ne!(
213              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
214              Register::<CurrentNetwork>::Access(3, vec![Access::Index(U32::new(0))])
215          );
216          assert_ne!(
217              Register::<CurrentNetwork>::Access(0, vec![Access::Index(U32::new(0))]),
218              Register::<CurrentNetwork>::Access(4, vec![Access::Index(U32::new(0))])
219          );
220  
221          // Register::Access with a combination of Access::Member and Access::Index
222          assert_eq!(
223              Register::<CurrentNetwork>::Access(0, vec![
224                  Access::Member(Identifier::from_str("owner")?),
225                  Access::Index(U32::new(0))
226              ]),
227              Register::<CurrentNetwork>::Access(0, vec![
228                  Access::Member(Identifier::from_str("owner")?),
229                  Access::Index(U32::new(0))
230              ])
231          );
232          assert_ne!(
233              Register::<CurrentNetwork>::Access(0, vec![
234                  Access::Member(Identifier::from_str("owner")?),
235                  Access::Index(U32::new(0))
236              ]),
237              Register::<CurrentNetwork>::Access(1, vec![
238                  Access::Member(Identifier::from_str("owner")?),
239                  Access::Index(U32::new(0))
240              ])
241          );
242          assert_ne!(
243              Register::<CurrentNetwork>::Access(0, vec![
244                  Access::Member(Identifier::from_str("owner")?),
245                  Access::Index(U32::new(0))
246              ]),
247              Register::<CurrentNetwork>::Access(2, vec![
248                  Access::Member(Identifier::from_str("owner")?),
249                  Access::Index(U32::new(0))
250              ])
251          );
252          assert_ne!(
253              Register::<CurrentNetwork>::Access(0, vec![
254                  Access::Member(Identifier::from_str("owner")?),
255                  Access::Index(U32::new(0))
256              ]),
257              Register::<CurrentNetwork>::Access(3, vec![
258                  Access::Member(Identifier::from_str("owner")?),
259                  Access::Index(U32::new(0))
260              ])
261          );
262          assert_ne!(
263              Register::<CurrentNetwork>::Access(0, vec![
264                  Access::Member(Identifier::from_str("owner")?),
265                  Access::Index(U32::new(0))
266              ]),
267              Register::<CurrentNetwork>::Access(4, vec![
268                  Access::Member(Identifier::from_str("owner")?),
269                  Access::Index(U32::new(0))
270              ])
271          );
272  
273          Ok(())
274      }
275  }