tehuti 0.22.0

Modular communication system for game development.
Documentation
use crate::replication::{Buffer, Replicable};
use serde::{Deserialize, Serialize};
use std::{
    error::Error,
    hash::{Hash, Hasher},
    io::{Read, Write},
    ops::{Deref, DerefMut},
};

impl Replicable for bool {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let byte = if *self { 1u8 } else { 0u8 };
        buffer.write_all(&[byte])?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut byte = [0u8; 1];
        buffer.read_exact(&mut byte)?;
        *self = byte[0] != 0;
        Ok(())
    }
}

macro_rules! impl_replicable_for_pod {
    ($($t:ty => $mode:ident),* $(,)?) => {
        $(
            impl Replicable for $t {
                fn collect_changes(
                    &self,
                    buffer: &mut Buffer,
                ) -> Result<(), Box<dyn Error>> {
                    leb128::write::$mode(buffer, *self as _)?;
                    Ok(())
                }

                fn apply_changes(
                    &mut self,
                    buffer: &mut Buffer,
                ) -> Result<(), Box<dyn Error>> {
                    *self = leb128::read::$mode(buffer)? as _;
                    Ok(())
                }
            }
        )*
    };
}

impl_replicable_for_pod!(
    u16 => unsigned,
    u32 => unsigned,
    u64 => unsigned,
    u128 => unsigned,
    usize => unsigned,
    i16 => signed,
    i32 => signed,
    i64 => signed,
    i128 => signed,
    isize => signed,
);

impl Replicable for u8 {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        buffer.write_all(&self.to_le_bytes())?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut byte = [0u8; 1];
        buffer.read_exact(&mut byte)?;
        *self = u8::from_le_bytes(byte);
        Ok(())
    }
}

impl Replicable for i8 {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        buffer.write_all(&self.to_le_bytes())?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut byte = [0u8; 1];
        buffer.read_exact(&mut byte)?;
        *self = i8::from_le_bytes(byte);
        Ok(())
    }
}

impl Replicable for f32 {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        buffer.write_all(&self.to_le_bytes())?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut buf = [0u8; std::mem::size_of::<f32>()];
        buffer.read_exact(&mut buf)?;
        *self = f32::from_le_bytes(buf);
        Ok(())
    }
}

impl Replicable for f64 {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        buffer.write_all(&self.to_le_bytes())?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut buf = [0u8; std::mem::size_of::<f64>()];
        buffer.read_exact(&mut buf)?;
        *self = f64::from_le_bytes(buf);
        Ok(())
    }
}

impl Replicable for char {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let code = *self as u32;
        buffer.write_all(&code.to_le_bytes())?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut buf = [0u8; std::mem::size_of::<u32>()];
        buffer.read_exact(&mut buf)?;
        let code = u32::from_le_bytes(buf);
        *self = std::char::from_u32(code).ok_or("Invalid char code")?;
        Ok(())
    }
}

impl Replicable for String {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let bytes = self.as_bytes();
        let len = bytes.len() as u64;
        buffer.write_all(&len.to_le_bytes())?;
        buffer.write_all(bytes)?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        let mut len_buf = [0u8; std::mem::size_of::<u64>()];
        buffer.read_exact(&mut len_buf)?;
        let len = u64::from_le_bytes(len_buf) as usize;
        let mut bytes = vec![0u8; len];
        buffer.read_exact(&mut bytes)?;
        *self = String::from_utf8(bytes)?;
        Ok(())
    }
}

macro_rules! impl_rep_float {
    ($( $wrap:ident => $type:ident ),+) => {
        $(
            #[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd, Serialize, Deserialize)]
            pub struct $wrap(pub $type);

            impl From<$type> for $wrap {
                fn from(value: $type) -> Self {
                    Self(value)
                }
            }

            impl From<$wrap> for $type {
                fn from(value: $wrap) -> Self {
                    value.0
                }
            }

            impl Deref for $wrap {
                type Target = $type;

                fn deref(&self) -> &Self::Target {
                    &self.0
                }
            }

            impl DerefMut for $wrap {
                fn deref_mut(&mut self) -> &mut Self::Target {
                    &mut self.0
                }
            }

            impl Hash for $wrap {
                fn hash<H: Hasher>(&self, state: &mut H) {
                    self.0.to_bits().hash(state);
                }
            }

            impl Replicable for $wrap {
                fn collect_changes(
                    &self,
                    buffer: &mut Buffer,
                ) -> Result<(), Box<dyn Error>> {
                    self.0.collect_changes(buffer)?;
                    Ok(())
                }

                fn apply_changes(
                    &mut self,
                    buffer: &mut Buffer,
                ) -> Result<(), Box<dyn Error>> {
                    self.0.apply_changes(buffer)?;
                    Ok(())
                }
            }
        )+
    };
}
impl_rep_float!(RepF32 => f32, RepF64 => f64);

#[derive(
    Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
)]
pub struct RepChar(pub char);

impl From<char> for RepChar {
    fn from(value: char) -> Self {
        Self(value)
    }
}

impl From<RepChar> for char {
    fn from(value: RepChar) -> Self {
        value.0
    }
}

impl Deref for RepChar {
    type Target = char;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for RepChar {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl Replicable for RepChar {
    fn collect_changes(&self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        leb128::write::unsigned(buffer, self.0 as u64)?;
        Ok(())
    }

    fn apply_changes(&mut self, buffer: &mut Buffer) -> Result<(), Box<dyn Error>> {
        self.0 =
            std::char::from_u32(leb128::read::unsigned(buffer)? as u32).ok_or("Invalid char")?;
        Ok(())
    }
}