use std::borrow::Borrow;
use std::cmp::Ordering;
use std::mem;
pub trait Key {
fn to_bytes(&self) -> Vec<u8>;
}
#[derive(Clone, PartialOrd, Ord, Debug)]
#[repr(transparent)]
pub struct ByteString {
bytes: Vec<u8>,
}
impl ByteString {
pub fn new(bytes: &[u8]) -> Self {
Self {
bytes: bytes.to_vec(),
}
}
}
impl Borrow<[u8]> for ByteString {
fn borrow(&self) -> &[u8] {
&self.bytes
}
}
impl Key for ByteString {
fn to_bytes(&self) -> Vec<u8> {
self.bytes.clone()
}
}
impl Eq for ByteString {}
impl PartialEq for ByteString {
fn eq(&self, other: &Self) -> bool {
self.bytes == other.bytes
}
}
impl Key for usize {
fn to_bytes(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}
impl Key for u8 {
fn to_bytes(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}
impl Key for u16 {
fn to_bytes(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}
impl Key for u32 {
fn to_bytes(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}
impl Key for u64 {
fn to_bytes(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}
impl Key for u128 {
fn to_bytes(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
}
impl Key for i8 {
fn to_bytes(&self) -> Vec<u8> {
let v: u8 = unsafe { mem::transmute(*self) };
let i = (v ^ 0x80) & 0x80;
let j = i | (v & 0x7F);
j.to_be_bytes().to_vec()
}
}
impl Key for i16 {
fn to_bytes(&self) -> Vec<u8> {
let v: u16 = unsafe { mem::transmute(*self) };
let xor = 1 << 15;
let i = (v ^ xor) & xor;
let j = i | (v & (u16::MAX >> 1));
j.to_be_bytes().to_vec()
}
}
impl Key for i32 {
fn to_bytes(&self) -> Vec<u8> {
let v: u32 = unsafe { mem::transmute(*self) };
let xor = 1 << 31;
let i = (v ^ xor) & xor;
let j = i | (v & (u32::MAX >> 1));
j.to_be_bytes().to_vec()
}
}
impl Key for i64 {
fn to_bytes(&self) -> Vec<u8> {
let v: u64 = unsafe { mem::transmute(*self) };
let xor = 1 << 63;
let i = (v ^ xor) & xor;
let j = i | (v & (u64::MAX >> 1));
j.to_be_bytes().to_vec()
}
}
impl Key for i128 {
fn to_bytes(&self) -> Vec<u8> {
let v: u128 = unsafe { mem::transmute(*self) };
let xor = 1 << 127;
let i = (v ^ xor) & xor;
let j = i | (v & (u128::MAX >> 1));
j.to_be_bytes().to_vec()
}
}
#[derive(Clone, Debug)]
#[repr(transparent)]
pub struct Float32 {
key: [u8; 4],
}
impl Borrow<[u8]> for Float32 {
fn borrow(&self) -> &[u8] {
&self.key
}
}
impl Eq for Float32 {}
impl PartialEq<Float32> for Float32 {
fn eq(&self, other: &Self) -> bool {
self.key == other.key
}
}
impl Ord for Float32 {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
impl PartialOrd<Float32> for Float32 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.key.cmp(&other.key))
}
}
impl From<f32> for Float32 {
fn from(v: f32) -> Self {
let v: u32 = v.to_bits();
let xor = 1 << 31;
let i = (v ^ xor) & xor;
let j = i | (v & (u32::MAX >> 1));
Self {
key: j.to_be_bytes(),
}
}
}
#[derive(Clone, Debug)]
#[repr(transparent)]
pub struct Float64 {
key: [u8; 8],
}
impl Borrow<[u8]> for Float64 {
fn borrow(&self) -> &[u8] {
&self.key
}
}
impl Eq for Float64 {}
impl PartialEq<Float64> for Float64 {
fn eq(&self, other: &Self) -> bool {
self.key == other.key
}
}
impl Ord for Float64 {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
impl PartialOrd<Float64> for Float64 {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.key.cmp(&other.key))
}
}
impl From<f64> for Float64 {
fn from(v: f64) -> Self {
let v: u64 = v.to_bits();
let xor = 1 << 63;
let i = (v ^ xor) & xor;
let j = i | (v & (u64::MAX >> 1));
Self {
key: j.to_be_bytes(),
}
}
}
impl Key for Float32 {
fn to_bytes(&self) -> Vec<u8> {
self.key.to_vec()
}
}
impl Key for Float64 {
fn to_bytes(&self) -> Vec<u8> {
self.key.to_vec()
}
}
#[repr(transparent)]
pub struct KeyBuilder {
key: ByteString,
}
impl Default for KeyBuilder {
fn default() -> Self {
Self::new()
}
}
impl KeyBuilder {
pub fn new() -> Self {
Self {
key: ByteString { bytes: Vec::new() },
}
}
pub fn with_capacity(cap: usize) -> Self {
Self {
key: ByteString {
bytes: Vec::with_capacity(cap),
},
}
}
pub fn append(mut self, key_part: impl Key) -> Self {
self.key.bytes.append(&mut key_part.to_bytes());
self
}
pub fn build(self) -> ByteString {
self.key
}
}