Skip to main content

miden_field/word/
lexicographic.rs

1use core::cmp::Ordering;
2
3#[cfg(not(all(target_family = "wasm", miden)))]
4use super::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
5use crate::{Felt, Word, word::WORD_SIZE_FELTS};
6
7// LEXICOGRAPHIC WORD
8// ================================================================================================
9
10/// A [`Word`] wrapper with lexicographic ordering.
11///
12/// This is a wrapper around any [`Word`] convertible type that overrides the equality and ordering
13/// implementations with a lexigographic one based on the wrapped type's [`Word`] representation.
14#[derive(Debug, Clone, Copy)]
15pub struct LexicographicWord<T: Into<Word> = Word>(T);
16
17impl<T: Into<Word>> LexicographicWord<T> {
18    /// Wraps the provided value into a new [`LexicographicWord`].
19    pub fn new(inner: T) -> Self {
20        Self(inner)
21    }
22
23    /// Returns a reference to the inner value.
24    pub fn inner(&self) -> &T {
25        &self.0
26    }
27
28    /// Consumes self and returns the inner value.
29    pub fn into_inner(self) -> T {
30        self.0
31    }
32}
33
34impl From<[Felt; WORD_SIZE_FELTS]> for LexicographicWord {
35    fn from(value: [Felt; WORD_SIZE_FELTS]) -> Self {
36        Self(value.into())
37    }
38}
39
40impl From<Word> for LexicographicWord {
41    fn from(word: Word) -> Self {
42        Self(word)
43    }
44}
45
46impl<T: Into<Word>> From<LexicographicWord<T>> for Word {
47    fn from(key: LexicographicWord<T>) -> Self {
48        key.0.into()
49    }
50}
51
52impl<T: Into<Word> + Copy> PartialEq for LexicographicWord<T> {
53    fn eq(&self, other: &Self) -> bool {
54        let self_word: Word = self.0.into();
55        let other_word: Word = other.0.into();
56        self_word == other_word
57    }
58}
59
60impl<T: Into<Word> + Copy> Eq for LexicographicWord<T> {}
61
62impl<T: Into<Word> + Copy> PartialOrd for LexicographicWord<T> {
63    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
64        Some(self.cmp(other))
65    }
66}
67
68impl<T: Into<Word> + Copy> Ord for LexicographicWord<T> {
69    fn cmp(&self, other: &Self) -> Ordering {
70        let self_word: Word = self.0.into();
71        let other_word: Word = other.0.into();
72
73        self_word.cmp(&other_word)
74    }
75}
76
77// SERIALIZATION
78// ================================================================================================
79
80#[cfg(not(all(target_family = "wasm", miden)))]
81impl<T: Into<Word> + Copy> Serializable for LexicographicWord<T> {
82    fn write_into<W: ByteWriter>(&self, target: &mut W) {
83        self.0.into().write_into(target);
84    }
85
86    fn get_size_hint(&self) -> usize {
87        self.0.into().get_size_hint()
88    }
89}
90
91#[cfg(not(all(target_family = "wasm", miden)))]
92impl<T: Into<Word> + From<Word>> Deserializable for LexicographicWord<T> {
93    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
94        let word = Word::read_from(source)?;
95
96        Ok(Self::new(T::from(word)))
97    }
98}
99
100// TESTS
101// ================================================================================================
102
103#[cfg(test)]
104mod tests {
105
106    use super::*;
107
108    #[derive(Debug, Clone, Copy)]
109    struct NoteId(Word);
110
111    impl From<Word> for NoteId {
112        fn from(value: Word) -> Self {
113            Self(value)
114        }
115    }
116
117    impl From<NoteId> for Word {
118        fn from(value: NoteId) -> Self {
119            value.0
120        }
121    }
122
123    #[test]
124    fn lexicographic_serialization() {
125        let word = Word::from([1u64, 2, 3, 4].map(Felt::new));
126        let key = LexicographicWord::new(word);
127        let bytes = key.to_bytes();
128        let deserialized_key = LexicographicWord::<Word>::read_from_bytes(&bytes).unwrap();
129        assert_eq!(key, deserialized_key);
130
131        let note_id = NoteId::from(word);
132        let key = LexicographicWord::new(note_id);
133        let bytes = key.to_bytes();
134        let deserialized_key = LexicographicWord::<NoteId>::read_from_bytes(&bytes).unwrap();
135        assert_eq!(key, deserialized_key);
136    }
137}