crystal-server 0.1.0

The client of a back-end provider to create multiplayer games.
Documentation
use std::{
    hash::Hash,
    ops::{Deref, DerefMut},
};

use integer_hasher::IsEnabled;
#[cfg(feature = "__dev")]
use tracing::warn;

pub struct LebCodec;

impl LebCodec {
    #[inline(always)]
    pub fn encode(mut number: u64) -> ([u8; 16], usize) {
        let mut leb = [0u8; 16];
        let mut pos = 0;
        loop {
            let n = number & 0x7f;
            number >>= 7;
            if number == 0 {
                leb[pos] = n as u8;
                pos += 1;
                break;
            } else {
                leb[pos] = (n | 0x80) as u8;
            }
            pos += 1;
        }
        (leb, pos)
    }

    #[inline(always)]
    pub fn decode(data: &[u8]) -> u64 {
        let mut num = 0;
        let mut shift = 0;
        let mut pos = 0;
        loop {
            if pos >= data.len() {
                #[cfg(feature = "__dev")]
                warn!("Unexpected data end for LEB128 decoder: The number may be truncated or incorrect.");
                break;
            }
            num |= ((data[pos] as u64) & 0x7f).wrapping_shl(shift);
            if data[pos] & 0x80 == 0 {
                break;
            }
            shift += 7;
            pos += 1;
        }
        num
    }
}

#[derive(Clone, Copy, Eq, Debug, Default)]
pub struct Leb<T: Into<u64> + Copy + PartialEq + Eq>(pub T);

impl<T: Into<u64> + Copy + PartialEq + Eq> Deref for Leb<T> {
    type Target = T;

    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<T: Into<u64> + Copy + PartialEq + Eq> DerefMut for Leb<T> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<T: Into<u64> + Copy + PartialEq + Eq> IsEnabled for Leb<T> {}

impl<T: Into<u64> + Copy + PartialEq + Eq> Hash for Leb<T> {
    #[inline(always)]
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        state.write_u64(self.0.into());
    }
}

impl<T: Into<u64> + Copy + PartialEq + Eq> PartialEq for Leb<T> {
    fn eq(&self, other: &Self) -> bool {
        other.0.into() == self.0.into()
    }
}

impl<T: Into<u64> + Copy + PartialEq + Eq> PartialOrd for Leb<T> {
    #[inline(always)]
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        Some(self.0.into().cmp(&other.0.into()))
    }
}

impl<T: Into<u64> + Copy + PartialEq + Eq> Ord for Leb<T> {
    #[inline(always)]
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.0.into().cmp(&other.0.into())
    }
}