1use crate::ToOrderableBytes;
64
65impl ToOrderableBytes for bool {
66 const ENCODED_LEN: usize = 1;
67 type Bytes = [u8; Self::ENCODED_LEN];
68
69 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
70 [*self as u8]
73 }
74}
75
76impl ToOrderableBytes for u8 {
77 const ENCODED_LEN: usize = 1;
78 type Bytes = [u8; Self::ENCODED_LEN];
79
80 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
81 [*self]
82 }
83}
84
85impl ToOrderableBytes for i8 {
86 const ENCODED_LEN: usize = 1;
87 type Bytes = [u8; Self::ENCODED_LEN];
88
89 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
90 [(*self as u8) ^ (1u8 << 7)]
91 }
92}
93
94impl ToOrderableBytes for u16 {
95 const ENCODED_LEN: usize = 2;
96 type Bytes = [u8; Self::ENCODED_LEN];
97
98 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
99 self.to_be_bytes()
100 }
101}
102
103impl ToOrderableBytes for i16 {
104 const ENCODED_LEN: usize = 2;
105 type Bytes = [u8; Self::ENCODED_LEN];
106
107 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
108 ((*self as u16) ^ (1u16 << 15)).to_be_bytes()
109 }
110}
111
112impl ToOrderableBytes for u32 {
113 const ENCODED_LEN: usize = 4;
114 type Bytes = [u8; Self::ENCODED_LEN];
115
116 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
117 self.to_be_bytes()
118 }
119}
120
121impl ToOrderableBytes for i32 {
122 const ENCODED_LEN: usize = 4;
123 type Bytes = [u8; Self::ENCODED_LEN];
124
125 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
126 ((*self as u32) ^ (1u32 << 31)).to_be_bytes()
127 }
128}
129
130impl ToOrderableBytes for u64 {
131 const ENCODED_LEN: usize = 8;
132 type Bytes = [u8; Self::ENCODED_LEN];
133
134 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
135 self.to_be_bytes()
136 }
137}
138
139impl ToOrderableBytes for i64 {
140 const ENCODED_LEN: usize = 8;
141 type Bytes = [u8; Self::ENCODED_LEN];
142
143 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
144 ((*self as u64) ^ (1u64 << 63)).to_be_bytes()
145 }
146}
147
148impl ToOrderableBytes for u128 {
149 const ENCODED_LEN: usize = 16;
150 type Bytes = [u8; Self::ENCODED_LEN];
151
152 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
153 self.to_be_bytes()
154 }
155}
156
157impl ToOrderableBytes for i128 {
158 const ENCODED_LEN: usize = 16;
159 type Bytes = [u8; Self::ENCODED_LEN];
160
161 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
162 ((*self as u128) ^ (1u128 << 127)).to_be_bytes()
163 }
164}
165
166impl ToOrderableBytes for char {
167 const ENCODED_LEN: usize = 4;
168 type Bytes = [u8; Self::ENCODED_LEN];
169
170 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
171 (*self as u32).to_be_bytes()
172 }
173}
174
175impl ToOrderableBytes for f32 {
176 const ENCODED_LEN: usize = 4;
177 type Bytes = [u8; Self::ENCODED_LEN];
178
179 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
180 let value = if *self == -0.0 { 0.0 } else { *self };
183 let bits = value.to_bits();
184 let sign_extension = (bits as i32 >> 31) as u32;
186 let mask = sign_extension | (1u32 << 31);
187 (bits ^ mask).to_be_bytes()
188 }
189}
190
191impl ToOrderableBytes for f64 {
192 const ENCODED_LEN: usize = 8;
193 type Bytes = [u8; Self::ENCODED_LEN];
194
195 fn to_orderable_bytes(&self) -> [u8; Self::ENCODED_LEN] {
196 let value = if *self == -0.0 { 0.0 } else { *self };
199 let bits = value.to_bits();
200 let sign_extension = (bits as i64 >> 63) as u64;
206 let mask = sign_extension | (1u64 << 63);
207 (bits ^ mask).to_be_bytes()
208 }
209}
210
211#[cfg(test)]
212mod tests {
213 use super::*;
214
215 #[test]
218 fn bool_known_anchors() {
219 assert_eq!(false.to_orderable_bytes(), [0x00]);
220 assert_eq!(true.to_orderable_bytes(), [0x01]);
221 }
222
223 #[test]
224 fn bool_byte_order_matches_natural_order() {
225 assert!(false.to_orderable_bytes() < true.to_orderable_bytes());
226 }
227
228 #[test]
231 fn u8_known_anchors() {
232 assert_eq!(u8::MIN.to_orderable_bytes(), [0x00]);
234 assert_eq!(0x42u8.to_orderable_bytes(), [0x42]);
235 assert_eq!(u8::MAX.to_orderable_bytes(), [0xFF]);
236 }
237
238 #[test]
239 fn u8_byte_order_matches_natural_order() {
240 let ascending = [u8::MIN, 1, 100, 200, u8::MAX];
241 for window in ascending.windows(2) {
242 assert!(
243 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
244 "{} < {} failed",
245 window[0],
246 window[1]
247 );
248 }
249 }
250
251 #[test]
254 fn i8_known_anchors() {
255 assert_eq!(i8::MIN.to_orderable_bytes(), [0x00]);
257 assert_eq!(0i8.to_orderable_bytes(), [0x80]);
258 assert_eq!(i8::MAX.to_orderable_bytes(), [0xFF]);
259 }
260
261 #[test]
262 fn i8_byte_order_matches_natural_order() {
263 let ascending = [i8::MIN, -100, -1, 0, 1, 100, i8::MAX];
264 for window in ascending.windows(2) {
265 assert!(
266 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
267 "{} < {} failed",
268 window[0],
269 window[1]
270 );
271 }
272 }
273
274 #[test]
277 fn u16_known_anchors() {
278 assert_eq!(u16::MIN.to_orderable_bytes(), [0x00, 0x00]);
279 assert_eq!(u16::MAX.to_orderable_bytes(), [0xFF, 0xFF]);
280 assert_eq!(0x1234u16.to_orderable_bytes(), [0x12, 0x34]);
281 }
282
283 #[test]
284 fn u16_byte_order_matches_natural_order() {
285 let ascending = [u16::MIN, 1, 256, 10000, u16::MAX - 1, u16::MAX];
286 for window in ascending.windows(2) {
287 assert!(
288 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
289 "{} < {} failed",
290 window[0],
291 window[1]
292 );
293 }
294 }
295
296 #[test]
299 fn i16_known_anchors() {
300 assert_eq!(i16::MIN.to_orderable_bytes(), [0x00, 0x00]);
302 assert_eq!(0i16.to_orderable_bytes(), [0x80, 0x00]);
303 assert_eq!(i16::MAX.to_orderable_bytes(), [0xFF, 0xFF]);
304 }
305
306 #[test]
307 fn i16_byte_order_matches_natural_order() {
308 let ascending = [i16::MIN, -10000, -1, 0, 1, 10000, i16::MAX];
309 for window in ascending.windows(2) {
310 assert!(
311 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
312 "{} < {} failed",
313 window[0],
314 window[1]
315 );
316 }
317 }
318
319 #[test]
322 fn u32_known_anchors() {
323 assert_eq!(u32::MIN.to_orderable_bytes(), [0x00; 4]);
324 assert_eq!(u32::MAX.to_orderable_bytes(), [0xFF; 4]);
325 assert_eq!(
326 0x1234_5678u32.to_orderable_bytes(),
327 [0x12, 0x34, 0x56, 0x78]
328 );
329 }
330
331 #[test]
332 fn u32_byte_order_matches_natural_order() {
333 let ascending = [
334 u32::MIN,
335 1,
336 1 << 8,
337 1 << 16,
338 1 << 24,
339 u32::MAX - 1,
340 u32::MAX,
341 ];
342 for window in ascending.windows(2) {
343 assert!(
344 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
345 "{} < {} failed",
346 window[0],
347 window[1]
348 );
349 }
350 }
351
352 #[test]
355 fn i32_known_anchors() {
356 assert_eq!(i32::MIN.to_orderable_bytes(), [0x00, 0x00, 0x00, 0x00]);
358 assert_eq!(0i32.to_orderable_bytes(), [0x80, 0x00, 0x00, 0x00]);
359 assert_eq!(i32::MAX.to_orderable_bytes(), [0xFF, 0xFF, 0xFF, 0xFF]);
360 }
361
362 #[test]
363 fn i32_byte_order_matches_natural_order() {
364 let ascending = [i32::MIN, -1_000_000_000, -1, 0, 1, 1_000_000_000, i32::MAX];
365 for window in ascending.windows(2) {
366 assert!(
367 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
368 "{} < {} failed",
369 window[0],
370 window[1]
371 );
372 }
373 }
374
375 #[test]
378 fn u64_known_anchors() {
379 assert_eq!(u64::MIN.to_orderable_bytes(), [0x00; 8]);
380 assert_eq!(u64::MAX.to_orderable_bytes(), [0xFF; 8]);
381 let one = 1u64.to_orderable_bytes();
382 let mut expected_one = [0u8; 8];
383 expected_one[7] = 1;
384 assert_eq!(one, expected_one);
385 }
386
387 #[test]
388 fn u64_byte_order_matches_natural_order() {
389 let ascending = [
390 u64::MIN,
391 1,
392 1 << 16,
393 1 << 32,
394 1 << 48,
395 u64::MAX - 1,
396 u64::MAX,
397 ];
398 for window in ascending.windows(2) {
399 assert!(
400 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
401 "{} < {} failed",
402 window[0],
403 window[1]
404 );
405 }
406 }
407
408 #[test]
411 fn i64_known_anchors() {
412 assert_eq!(i64::MIN.to_orderable_bytes(), [0x00; 8]);
413 assert_eq!(
414 0i64.to_orderable_bytes(),
415 [0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
416 );
417 assert_eq!(i64::MAX.to_orderable_bytes(), [0xFF; 8]);
418 }
419
420 #[test]
421 fn i64_byte_order_matches_natural_order() {
422 let ascending = [
423 i64::MIN,
424 -1_000_000_000_000,
425 -1,
426 0,
427 1,
428 1_000_000_000_000,
429 i64::MAX,
430 ];
431 for window in ascending.windows(2) {
432 assert!(
433 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
434 "{} < {} failed",
435 window[0],
436 window[1]
437 );
438 }
439 }
440
441 #[test]
444 fn u128_known_anchors() {
445 assert_eq!(u128::MIN.to_orderable_bytes(), [0; 16]);
446 assert_eq!(u128::MAX.to_orderable_bytes(), [0xFF; 16]);
447 let one = 1u128.to_orderable_bytes();
448 let mut expected_one = [0u8; 16];
449 expected_one[15] = 1;
450 assert_eq!(one, expected_one);
451 }
452
453 #[test]
454 fn u128_byte_order_matches_natural_order() {
455 let ascending = [
456 u128::MIN,
457 1,
458 (1u128 << 32),
459 (1u128 << 64),
460 (1u128 << 96),
461 u128::MAX - 1,
462 u128::MAX,
463 ];
464 for window in ascending.windows(2) {
465 assert!(
466 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
467 "{} < {} failed",
468 window[0],
469 window[1]
470 );
471 }
472 }
473
474 #[test]
477 fn i128_known_anchors() {
478 assert_eq!(i128::MIN.to_orderable_bytes(), [0; 16]);
479 assert_eq!(i128::MAX.to_orderable_bytes(), [0xFF; 16]);
480 let mut expected_zero = [0u8; 16];
481 expected_zero[0] = 0x80;
482 assert_eq!(0i128.to_orderable_bytes(), expected_zero);
483 }
484
485 #[test]
486 fn i128_byte_order_matches_natural_order() {
487 let ascending = [
488 i128::MIN,
489 -(1i128 << 96),
490 -(1i128 << 64),
491 -1,
492 0,
493 1,
494 (1i128 << 64),
495 (1i128 << 96),
496 i128::MAX,
497 ];
498 for window in ascending.windows(2) {
499 assert!(
500 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
501 "{} < {} failed",
502 window[0],
503 window[1]
504 );
505 }
506 }
507
508 #[test]
511 fn char_known_anchors() {
512 assert_eq!('A'.to_orderable_bytes(), [0x00, 0x00, 0x00, 0x41]);
514 assert_eq!('\0'.to_orderable_bytes(), [0x00, 0x00, 0x00, 0x00]);
516 assert_eq!(char::MAX.to_orderable_bytes(), [0x00, 0x10, 0xFF, 0xFF]);
518 }
519
520 #[test]
521 fn char_byte_order_matches_natural_order() {
522 let ascending = [
524 '\0',
525 '0',
526 'A',
527 'a',
528 '\u{7F}',
529 '\u{D7FF}',
530 '\u{E000}',
531 '\u{1F600}',
532 char::MAX,
533 ];
534 for window in ascending.windows(2) {
535 assert!(
536 window[0].to_orderable_bytes() < window[1].to_orderable_bytes(),
537 "{:?} < {:?} failed",
538 window[0],
539 window[1]
540 );
541 }
542 }
543
544 #[test]
547 fn f32_zero_canonical_bytes() {
548 assert_eq!(0.0f32.to_orderable_bytes(), [0x80, 0x00, 0x00, 0x00]);
550 }
551
552 #[test]
553 fn f32_negative_zero_canonicalises_with_zero() {
554 assert_eq!((-0.0f32).to_orderable_bytes(), 0.0f32.to_orderable_bytes());
555 }
556
557 #[test]
558 fn f32_byte_order_matches_natural_order() {
559 let ascending = [
560 f32::NEG_INFINITY,
561 f32::MIN,
562 -1e30,
563 -1.0,
564 -f32::MIN_POSITIVE,
565 0.0,
566 f32::MIN_POSITIVE,
567 1.0,
568 1e30,
569 f32::MAX,
570 f32::INFINITY,
571 ];
572 for window in ascending.windows(2) {
573 let a = window[0].to_orderable_bytes();
574 let b = window[1].to_orderable_bytes();
575 assert!(a < b, "{} < {} failed", window[0], window[1]);
576 }
577 }
578
579 #[test]
580 fn f32_subnormals_sort_above_zero_below_normals() {
581 let subnormal = f32::from_bits(1);
584 assert!(0.0f32.to_orderable_bytes() < subnormal.to_orderable_bytes());
585 assert!(subnormal.to_orderable_bytes() < f32::MIN_POSITIVE.to_orderable_bytes());
586 }
587
588 #[test]
591 fn f64_zero_canonical_bytes() {
592 assert_eq!(
594 0.0f64.to_orderable_bytes(),
595 [0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
596 );
597 }
598
599 #[test]
600 fn f64_negative_zero_canonicalises_with_zero() {
601 assert_eq!((-0.0f64).to_orderable_bytes(), 0.0f64.to_orderable_bytes());
602 }
603
604 #[test]
605 fn f64_byte_order_matches_natural_order() {
606 let ascending = [
607 f64::NEG_INFINITY,
608 f64::MIN,
609 -1e100,
610 -1.0,
611 -f64::MIN_POSITIVE,
612 0.0,
613 f64::MIN_POSITIVE,
614 1.0,
615 1e100,
616 f64::MAX,
617 f64::INFINITY,
618 ];
619 for window in ascending.windows(2) {
620 let a = window[0].to_orderable_bytes();
621 let b = window[1].to_orderable_bytes();
622 assert!(a < b, "{} < {} failed", window[0], window[1]);
623 }
624 }
625
626 #[test]
627 fn f64_subnormals_sort_above_zero_below_normals() {
628 let subnormal = f64::from_bits(1);
631 assert!(0.0f64.to_orderable_bytes() < subnormal.to_orderable_bytes());
632 assert!(subnormal.to_orderable_bytes() < f64::MIN_POSITIVE.to_orderable_bytes());
633 }
634}