lexico 0.1.1

Lexicographically orderable number encodings
Documentation
// Based on https://cornerwings.github.io/2019/10/lexical-sorting/

use std::mem;

macro_rules! lu {
  ($t:ident) => {
    #[inline(always)]
    #[no_mangle]
    pub fn $t(x: $t) -> [u8; mem::size_of::<$t>()] {
      return x.to_be_bytes();
    }
  }
}

lu!(u8);
lu!(u16);
lu!(u32);
lu!(u64);
lu!(u128);

macro_rules! li {
  ($t:ident) => {
    #[inline(always)]
    #[no_mangle]
    pub fn $t(x: $t) -> [u8; mem::size_of::<$t>()] {
      return (x ^ $t::MIN).to_be_bytes();
    }
  }
}

li!(i8);
li!(i16);
li!(i32);
li!(i64);
li!(i128);

macro_rules! lf {
  ($t:ident, $i:ident) => {
    #[inline]
    #[no_mangle]
    pub fn $t(x: $t) -> [u8; mem::size_of::<$i>()] {
      let mut res = unsafe { mem::transmute::<$t, $i>(x) };
      if res < 0 { res = $i::MIN - res; }
      return $i(res);
    }
  }
}

lf!(f32, i32);
lf!(f64, i64);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_generates_lexically_ordered_byte_arrays() {
      assert_eq!(i128(56544), [ 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 224 ]);
      assert_eq!(u128(56544), [   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 224 ]);

      assert_eq!(i8(3), [ 131 ]);
      assert_eq!(i8(-128), [ 0 ]);
      assert_eq!(u8(255), [ 255 ]);

      assert_eq!(i16(-2), [ 127, 254 ]);
      assert_eq!(i16(2), [ 128, 2 ]);
      assert_eq!(u16(65535), [ 255, 255 ]);
      assert_eq!(i16(-32768), [ 0, 0 ]);

      assert_eq!(i32(5), [ 128, 0, 0, 5 ]);
      assert_eq!(u32(5), [ 0, 0, 0, 5 ]);
      assert_eq!(i32(-10), [ 127, 255, 255, 246 ]);

      assert_eq!(i64(-1), [ 127, 255, 255, 255, 255, 255, 255, 255 ]);
      assert_eq!(i64(100), [ 128, 0, 0, 0, 0, 0, 0, 100 ]);
      assert_eq!(u64(4_000_000_000_000_000u64), [ 0, 14, 53, 250, 147, 26, 0, 0 ]);

      assert_eq!(f32(4.2), [ 192, 134, 102, 102 ]);
      assert_eq!(f32(0.42), [ 190, 215, 10, 61 ]);
      assert_eq!(f32(-10.0), [ 62, 224, 0, 0 ]);
      assert_eq!(f32(2.1e6), [ 202, 0, 44, 128 ]);
      assert_eq!(f32(2.1e20), [ 225, 54, 37, 94 ]);
      assert_eq!(f32(-2.1e6), [ 53, 255, 211, 128 ]);

      assert_eq!(f64(-2.1e6), [ 62, 191, 250, 112, 0, 0, 0, 0 ]);
      assert_eq!(f64(2.1e2), [ 192, 106, 64, 0, 0, 0, 0, 0 ]);
      assert_eq!(f64(2.1000000001e2), [ 192, 106, 64, 0, 0, 5, 94, 100 ]);
    }
}