1pub mod raw;
2
3const fn compute_nbytes(nbits: usize) -> usize {
4 if nbits % 8 == 0 {
5 nbits / 8
6 } else {
7 (nbits / 8) + 1
8 }
9}
10
11const NBITS: usize = 35;
13const NBYTES: usize = compute_nbytes(NBITS);
14
15pub use raw::Direction;
16pub type Address = raw::Address<NBYTES>;
17pub type AddressIterator = raw::AddressIterator<NBYTES>;
18
19#[cfg(test)]
20mod tests {
21 use crate::AccountIndex;
22
23 use super::*;
24
25 #[cfg(target_family = "wasm")]
26 use wasm_bindgen_test::wasm_bindgen_test as test;
27
28 #[test]
29 fn test_address_iter() {
30 use Direction::*;
31
32 let addr = Address::try_from("10101010").unwrap();
33 assert_eq!(
34 addr.iter().collect::<Vec<_>>(),
35 &[Right, Left, Right, Left, Right, Left, Right, Left]
36 );
37
38 let addr = Address::try_from("01010101").unwrap();
39 assert_eq!(
40 addr.iter().collect::<Vec<_>>(),
41 &[Left, Right, Left, Right, Left, Right, Left, Right]
42 );
43
44 let addr = Address::try_from("010101010").unwrap();
45 assert_eq!(
46 addr.iter().collect::<Vec<_>>(),
47 &[Left, Right, Left, Right, Left, Right, Left, Right, Left]
48 );
49
50 let addr = Address::try_from("0101010101").unwrap();
51 assert_eq!(
52 addr.iter().collect::<Vec<_>>(),
53 &[Left, Right, Left, Right, Left, Right, Left, Right, Left, Right]
54 );
55
56 let addr = Address::try_from("").unwrap();
57 assert!(addr.iter().next().is_none());
58
59 assert!(Address::try_from("0101010101a").is_err());
60 assert!(Address::try_from("0".repeat((NBYTES * 8) - 1).as_str()).is_ok());
61 assert!(Address::try_from("0".repeat(NBYTES * 8).as_str()).is_err());
62 }
63
64 #[test]
65 fn test_address_next() {
66 let two: usize = 2;
67
68 for length in 5..23 {
70 let mut addr = Address::last(length);
71
72 elog!("length={length} until={:?}", two.pow(length as u32));
73 for _ in 0..two.pow(length as u32) - 1 {
74 let prev = addr.prev().unwrap();
75 assert_eq!(prev.next().unwrap(), addr);
76 addr = prev;
77 }
78
79 assert!(addr.prev().is_none());
80 }
81
82 for length in 5..23 {
84 let mut addr = Address::first(length);
85
86 elog!("length={length} until={:?}", two.pow(length as u32));
87 for _ in 0..two.pow(length as u32) - 1 {
88 let next = addr.next().unwrap();
89 assert_eq!(next.prev().unwrap(), addr);
90 addr = next;
91 }
92
93 assert!(addr.next().is_none());
94 }
95 }
96
97 #[test]
98 fn test_address_clear() {
99 let mut inner: [u8; NBYTES] = Default::default();
100 inner[0] = 0b11111111;
101 inner[1] = 0b11111111;
102
103 let mut addr = Address { inner, length: 12 };
104 elog!("ADDR={:?}", addr);
105 addr.clear_after(6);
106 elog!("ADDR={:?}", addr);
107 }
108
109 #[test]
110 fn test_address_can_reach() {
111 let addr = Address::try_from("00").unwrap();
112 assert!(addr.is_before(&Address::try_from("00").unwrap()));
113 assert!(addr.is_before(&Address::try_from("01").unwrap()));
114 assert!(addr.is_before(&Address::try_from("000").unwrap()));
115 assert!(addr.is_before(&Address::try_from("001").unwrap()));
116 assert!(addr.is_before(&Address::try_from("010").unwrap()));
117 assert!(addr.is_before(&Address::try_from("100").unwrap()));
118
119 let addr = Address::try_from("101").unwrap();
120 assert!(addr.is_before(&Address::try_from("10100").unwrap()));
121 assert!(addr.is_before(&Address::try_from("10111").unwrap()));
122 assert!(!addr.is_before(&Address::try_from("10011").unwrap()));
123 }
124
125 #[test]
126 fn test_address_show() {
127 let addr = Address::first(2);
128 elog!("LA {:?}", addr);
129 let sec = addr.next().unwrap();
130 elog!("LA {:?}", sec);
131 elog!("LA {:?}", sec.child_left());
132 }
133
134 #[test]
135 fn test_address_index() {
136 for length in 1..20 {
137 let mut addr = Address::first(length);
138
139 for index in 0..2u64.pow(length as u32) - 1 {
140 let to_index = addr.to_index();
141
142 assert_eq!(to_index, AccountIndex(index));
143 assert_eq!(addr, Address::from_index(to_index, length));
144
145 addr = addr.next().unwrap();
146 }
147 }
148 }
149
150 #[test]
151 fn test_address_linear() {
152 for (index, s) in [
153 "", "0", "1", "00", "01", "10", "11", "000", "001", "010", "011", "100", "101", "110",
154 "111",
155 ]
156 .iter()
157 .enumerate()
158 {
159 let addr = Address::try_from(*s).unwrap();
160 assert_eq!(index as u64, addr.to_linear_index());
161 }
162 }
163
164 #[test]
165 fn test_address_children() {
166 let root = Address::try_from("00").unwrap();
167 let iter_children = root.iter_children(4);
168 assert_eq!(iter_children.len(), 4);
169 assert_eq!(
170 iter_children.collect::<Vec<_>>(),
171 &[
172 Address::try_from("0000").unwrap(),
173 Address::try_from("0001").unwrap(),
174 Address::try_from("0010").unwrap(),
175 Address::try_from("0011").unwrap(),
176 ]
177 );
178
179 let root = Address::try_from("01").unwrap();
180 let iter_children = root.iter_children(4);
181 assert_eq!(iter_children.len(), 4);
182 assert_eq!(
183 iter_children.collect::<Vec<_>>(),
184 &[
185 Address::try_from("0100").unwrap(),
186 Address::try_from("0101").unwrap(),
187 Address::try_from("0110").unwrap(),
188 Address::try_from("0111").unwrap(),
189 ]
190 );
191
192 let root = Address::try_from("10").unwrap();
193 let iter_children = root.iter_children(4);
194 assert_eq!(iter_children.len(), 4);
195 assert_eq!(
196 iter_children.collect::<Vec<_>>(),
197 &[
198 Address::try_from("1000").unwrap(),
199 Address::try_from("1001").unwrap(),
200 Address::try_from("1010").unwrap(),
201 Address::try_from("1011").unwrap(),
202 ]
203 );
204
205 let root = Address::try_from("11").unwrap();
206 let iter_children = root.iter_children(4);
207 assert_eq!(iter_children.len(), 4);
208 assert_eq!(
209 iter_children.collect::<Vec<_>>(),
210 &[
211 Address::try_from("1100").unwrap(),
212 Address::try_from("1101").unwrap(),
213 Address::try_from("1110").unwrap(),
214 Address::try_from("1111").unwrap(),
215 ]
216 );
217
218 let root = Address::try_from("00").unwrap();
219 let iter_children = root.iter_children(6);
220 assert_eq!(iter_children.len(), 16);
221 }
222
223 #[test]
224 fn test_address_children_parent_root_eq() {
225 let left = Address::first(1);
226 let right = left.next().unwrap();
227 assert_eq!(left.parent().unwrap(), Address::root());
228 assert_eq!(right.parent().unwrap(), Address::root());
229 assert_eq!(left.parent(), right.parent());
230 }
231}