substrate_median/
lexicographic.rs1use core::cmp::Ord;
2
3use scale::FullCodec;
4
5pub trait LexicographicEncoding: Ord + FullCodec {
7 type Encoding: AsMut<[u8]> + Ord + FullCodec;
11 fn lexicographic_encode(&self) -> Self::Encoding;
13 fn lexicographic_decode(encoding: Self::Encoding) -> Self;
15}
16
17macro_rules! impl_prim_uint {
18 ($type: ident) => {
19 impl LexicographicEncoding for $type {
20 type Encoding = [u8; core::mem::size_of::<Self>()];
21 fn lexicographic_encode(&self) -> Self::Encoding {
22 self.to_be_bytes()
23 }
24 fn lexicographic_decode(encoding: Self::Encoding) -> Self {
25 Self::from_be_bytes(encoding)
26 }
27 }
28 };
29}
30impl_prim_uint!(u8);
31impl_prim_uint!(u16);
32impl_prim_uint!(u32);
33impl_prim_uint!(u64);
34impl_prim_uint!(u128);
35
36pub struct LexicographicReverse<V: LexicographicEncoding>(V::Encoding);
42
43impl<V: LexicographicEncoding> scale::Decode for LexicographicReverse<V> {
44 fn decode<I: scale::Input>(input: &mut I) -> Result<Self, scale::Error> {
45 V::Encoding::decode(input).map(Self)
46 }
47}
48
49impl<V: LexicographicEncoding> scale::Encode for LexicographicReverse<V> {
50 fn size_hint(&self) -> usize {
51 self.0.size_hint()
52 }
53 fn encode_to<T: scale::Output + ?Sized>(&self, dest: &mut T) {
54 self.0.encode_to(dest)
55 }
56 fn encode(&self) -> Vec<u8> {
57 self.0.encode()
58 }
59 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
60 self.0.using_encoded(f)
61 }
62 fn encoded_size(&self) -> usize {
63 self.0.encoded_size()
64 }
65}
66
67impl<V: LexicographicEncoding> scale::EncodeLike for LexicographicReverse<V> {}
68
69fn reverse<E: AsMut<[u8]>>(mut encoding: E) -> E {
71 for byte in encoding.as_mut().iter_mut() {
72 *byte = !*byte;
73 }
74 encoding
75}
76
77impl<V: LexicographicEncoding> LexicographicReverse<V> {
78 pub(super) fn from_encoding(encoding: V::Encoding) -> Self {
79 Self(reverse(encoding))
80 }
81 pub(super) fn from(value: &V) -> Self {
82 Self::from_encoding(value.lexicographic_encode())
83 }
84 pub(super) fn into(self) -> V {
85 V::lexicographic_decode(reverse(self.0))
86 }
87}
88
89#[test]
90fn lexicographic_uint() {
91 use rand_core::{RngCore, OsRng};
92
93 {
95 assert_eq!(0u64.lexicographic_encode(), 0u64.lexicographic_encode());
96 assert!(0u64.lexicographic_encode() < 1u64.lexicographic_encode());
97 assert!(0u64.lexicographic_encode() <= 1u64.lexicographic_encode());
98 assert!(1u64.lexicographic_encode() > 0u64.lexicographic_encode());
99 assert!(1u64.lexicographic_encode() >= 0u64.lexicographic_encode());
100 }
101
102 for _ in 0 .. 100 {
104 let value = OsRng.next_u64();
105 assert_eq!(u64::lexicographic_decode(value.lexicographic_encode()), value);
106 }
107
108 for _ in 0 .. 100 {
110 let a = OsRng.next_u64();
111 let b = OsRng.next_u64();
112 assert_eq!(a.cmp(&b), a.lexicographic_encode().cmp(&b.lexicographic_encode()));
113 }
114}
115
116#[test]
117fn lexicographic_reverse() {
118 use rand_core::{RngCore, OsRng};
119
120 for _ in 0 .. 100 {
121 let a = OsRng.next_u64();
122 let b = loop {
123 let b = OsRng.next_u64();
124 if a != b {
125 break b;
126 }
127 };
128 let mut a_enc = a.lexicographic_encode();
129 let mut b_enc = b.lexicographic_encode();
130 assert_eq!(a_enc, a_enc);
131 assert_eq!(a.cmp(&b), a_enc.cmp(&b_enc));
132
133 assert_eq!(a.cmp(&b).reverse(), reverse(a_enc).cmp(&reverse(b_enc)));
134
135 assert_eq!(reverse(reverse(a_enc)), a_enc);
137 assert_eq!(reverse(reverse(b_enc)), b_enc);
138 assert_eq!(LexicographicReverse::<u64>::from_encoding(a.lexicographic_encode()).into(), a);
139 assert_eq!(LexicographicReverse::<u64>::from_encoding(b.lexicographic_encode()).into(), b);
140 assert_eq!(LexicographicReverse::from(&a).into(), a);
141 assert_eq!(LexicographicReverse::from(&b).into(), b);
142 }
143}