miden_objects/account/delta/
lexicographic_word.rs1use core::cmp::Ordering;
2
3use vm_core::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
4use vm_processor::DeserializationError;
5
6use crate::{Felt, Word};
7
8#[derive(Debug, Clone, Copy)]
13pub struct LexicographicWord<T: Into<Word> = Word>(T);
14
15impl<T: Into<Word>> LexicographicWord<T> {
16 pub fn new(inner: T) -> Self {
18 Self(inner)
19 }
20
21 pub fn inner(&self) -> &T {
23 &self.0
24 }
25
26 pub fn into_inner(self) -> T {
28 self.0
29 }
30}
31
32impl From<Word> for LexicographicWord {
33 fn from(word: Word) -> Self {
34 Self(word)
35 }
36}
37
38impl<T: Into<Word>> From<LexicographicWord<T>> for Word {
39 fn from(key: LexicographicWord<T>) -> Self {
40 key.0.into()
41 }
42}
43
44impl<T: Into<Word> + Copy> PartialEq for LexicographicWord<T> {
45 fn eq(&self, other: &Self) -> bool {
46 let self_word: Word = self.0.into();
47 let other_word: Word = other.0.into();
48 self_word == other_word
49 }
50}
51
52impl<T: Into<Word> + Copy> Eq for LexicographicWord<T> {}
53
54impl<T: Into<Word> + Copy> PartialOrd for LexicographicWord<T> {
55 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
56 Some(self.cmp(other))
57 }
58}
59
60impl<T: Into<Word> + Copy> Ord for LexicographicWord<T> {
61 fn cmp(&self, other: &Self) -> Ordering {
62 let self_word: Word = self.0.into();
63 let other_word: Word = other.0.into();
64
65 for (felt0, felt1) in self_word
66 .iter()
67 .rev()
68 .map(Felt::as_int)
69 .zip(other_word.iter().rev().map(Felt::as_int))
70 {
71 let ordering = felt0.cmp(&felt1);
72 if let Ordering::Less | Ordering::Greater = ordering {
73 return ordering;
74 }
75 }
76
77 Ordering::Equal
78 }
79}
80
81impl<T: Into<Word> + Copy> Serializable for LexicographicWord<T> {
85 fn write_into<W: ByteWriter>(&self, target: &mut W) {
86 self.0.into().write_into(target);
87 }
88
89 fn get_size_hint(&self) -> usize {
90 self.0.into().get_size_hint()
91 }
92}
93
94impl<T: Into<Word> + From<Word>> Deserializable for LexicographicWord<T> {
95 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
96 let word = Word::read_from(source)?;
97
98 Ok(Self::new(T::from(word)))
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105 use crate::note::NoteId;
106
107 #[test]
108 fn lexicographic_word_ordering() {
109 for (expected, key0, key1) in [
110 (Ordering::Equal, [0, 0, 0, 0u32], [0, 0, 0, 0u32]),
111 (Ordering::Greater, [1, 0, 0, 0u32], [0, 0, 0, 0u32]),
112 (Ordering::Greater, [0, 1, 0, 0u32], [0, 0, 0, 0u32]),
113 (Ordering::Greater, [0, 0, 1, 0u32], [0, 0, 0, 0u32]),
114 (Ordering::Greater, [0, 0, 0, 1u32], [0, 0, 0, 0u32]),
115 (Ordering::Less, [0, 0, 0, 0u32], [1, 0, 0, 0u32]),
116 (Ordering::Less, [0, 0, 0, 0u32], [0, 1, 0, 0u32]),
117 (Ordering::Less, [0, 0, 0, 0u32], [0, 0, 1, 0u32]),
118 (Ordering::Less, [0, 0, 0, 0u32], [0, 0, 0, 1u32]),
119 (Ordering::Greater, [0, 0, 0, 1u32], [1, 1, 1, 0u32]),
120 (Ordering::Greater, [0, 0, 1, 0u32], [1, 1, 0, 0u32]),
121 (Ordering::Less, [1, 1, 1, 0u32], [0, 0, 0, 1u32]),
122 (Ordering::Less, [1, 1, 0, 0u32], [0, 0, 1, 0u32]),
123 ] {
124 assert_eq!(
125 LexicographicWord::from(key0.map(Felt::from))
126 .cmp(&LexicographicWord::from(key1.map(Felt::from))),
127 expected
128 );
129 }
130 }
131
132 #[test]
133 fn lexicographic_serialization() {
134 let word = Word::from([1u64, 2, 3, 4].map(Felt::new));
135 let key = LexicographicWord::new(word);
136 let bytes = key.to_bytes();
137 let deserialized_key = LexicographicWord::<Word>::read_from_bytes(&bytes).unwrap();
138 assert_eq!(key, deserialized_key);
139
140 let note_id = NoteId::from(word);
141 let key = LexicographicWord::new(note_id);
142 let bytes = key.to_bytes();
143 let deserialized_key = LexicographicWord::<NoteId>::read_from_bytes(&bytes).unwrap();
144 assert_eq!(key, deserialized_key);
145 }
146}