acacia_net 0.1.0

A library for the Minecraft: Java Edition network protocol.
use std::{
    borrow::Cow,
    io::{Error as IoError, Read},
};

use byteorder::{ReadBytesExt, BE};

use super::types::{VarInt, VarLong, Position};

#[derive(Debug, Fail)]
pub enum ParseError {
    #[fail(display = "The packet was not long enough: {} more bytes needed", _0)]
    MoreNeeded(usize),
    #[fail(display = "Invalid Packet ID: {}", _0)]
    InvalidPacketId(i32),
    #[fail(display = "{} is not a discriminant of enum {}", _1, _0)]
    InvalidEnumDiscriminant(&'static str, i32),
    #[fail(display = "The packet was not long enough")]
    UnexpectedEof,
    #[fail(display = "VarInt too long")]
    VarIntTooLong,
    #[fail(display = "VarLong too long")]
    VarLongTooLong,
    #[fail(display = "String too long")]
    StringTooLong,
    #[fail(display = "String had negative length")]
    StringLengthNegative,
    #[fail(display = "String wasn't UTF-8")]
    StringNotUtf8,
    #[fail(display = "Bool wasn't 0 or 1")]
    InvalidBool,
    #[fail(display = "NBT parsing error: {}", _0)]
    NbtError(#[cause] nbt::Error),
    #[fail(display = "IO error: {}", _0)]
    IoError(#[cause] IoError),
}

impl From<IoError> for ParseError {
    fn from(io_error: IoError) -> Self {
        ParseError::IoError(io_error)
    }
}

impl From<nbt::Error> for ParseError {
    fn from(nbt_error: nbt::Error) -> Self {
        match nbt_error {
            nbt::Error::IoError(e) => ParseError::IoError(e),
            e => ParseError::NbtError(e),
        }
    }
}

pub(crate) trait Deserialise<Meta>: Sized {
    fn deserialise<R: Read>(reader: R, meta: Meta) -> Result<Self, ParseError>;
}

impl Deserialise<()> for nbt::Value {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let value = nbt::from_reader(&mut reader)?;
        Ok(value)
    }
}

impl Deserialise<()> for VarInt {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let mut ret = 0i32;
        let mut i = 0;
        let mut byte = [0];
        while let Ok(1) = reader.read(&mut byte) {
            let byte = byte[0];
            ret |= ((byte & 0b0111_1111) as i32) << (7 * i);
            i += 1;
            if byte & 0b1000_0000 == 0 {
                return Ok(VarInt(ret));
            }
            if i > 5 {
                return Err(ParseError::VarIntTooLong);
            }
        }
        Err(ParseError::UnexpectedEof)
    }
}

impl Deserialise<()> for VarLong {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let mut ret = 0i64;
        let mut i = 0;
        let mut byte = [0];
        while let Ok(1) = reader.read(&mut byte) {
            let byte = byte[0];
            ret |= ((byte & 0b0111_1111) as i64) << (7 * i);
            i += 1;
            if byte & 0b1000_0000 == 0 {
                return Ok(VarLong(ret));
            }
            if i > 10 {
                return Err(ParseError::VarLongTooLong);
            }
        }
        Err(ParseError::UnexpectedEof)
    }
}

impl Deserialise<()> for Position {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let v = u64::deserialise(&mut reader, ())?;
        let mut x = (v >> 38) as i64;
        let mut y = ((v >> 26) & 0xFFF) as i64;
        let mut z = (v & 0x3FF_FFFF) as i64;
        if x >= 2^25 { x -= 1 << 26 }
        if y >= 2^11 { y -= 1 << 12 }
        if z >= 2^25 { z -= 1 << 26 }
        Ok(Position(x, y, z))
    }
}

impl Deserialise<()> for Cow<'_, str> {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let VarInt(len) = VarInt::deserialise(&mut reader, ())?;
        if len < 0 {
            return Err(ParseError::StringLengthNegative);
        } else if len > 32767 {
            return Err(ParseError::StringTooLong);
        }

        let mut buf = vec![0; len as usize];
        reader.read_exact(&mut buf)?;
        let ret = String::from_utf8(buf).map_err(|_| ParseError::StringNotUtf8)?.into();
        Ok(ret)
    }
}

impl<T: Deserialise<()> + Clone> Deserialise<usize> for Cow<'_, [T]> {
    fn deserialise<R: Read>(mut reader: R, len: usize) -> Result<Self, ParseError> {
        let mut ret = Vec::<T>::with_capacity(len);
        for _ in 0..len {
            ret.push(T::deserialise(&mut reader, ())?);
        }
        Ok(ret.into())
    }
}

impl<T: Deserialise<()> + Clone> Deserialise<()> for Cow<'_, [T]> {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let mut ret = Vec::<T>::new();
        while let Ok(v) = T::deserialise(&mut reader, ()) {
            ret.push(v);
        }
        Ok(ret.into())
    }
}

impl<M: Copy, T: Deserialise<M> + Clone> Deserialise<(usize, M)> for Cow<'_, [T]> {
    fn deserialise<R: Read>(mut reader: R, (len, inner_meta): (usize, M)) -> Result<Self, ParseError> {
        let mut ret = Vec::<T>::with_capacity(len);
        for _ in 0..len {
            ret.push(T::deserialise(&mut reader, inner_meta)?);
        }
        Ok(ret.into())
    }
}

pub struct NoLengthHint;

impl<M: Copy, T: Deserialise<M> + Clone> Deserialise<(NoLengthHint, M)> for Cow<'_, [T]> {
    fn deserialise<R: Read>(mut reader: R, (_, inner_meta): (NoLengthHint, M)) -> Result<Self, ParseError> {
        let mut ret = Vec::<T>::new();
        while let Ok(v) = T::deserialise(&mut reader, inner_meta) {
            ret.push(v);
        }
        Ok(ret.into())
    }
}

impl<M, T: Deserialise<M>> Deserialise<(bool, M)> for Option<T> {
    fn deserialise<R: Read>(mut reader: R, (meta, inner_meta): (bool, M)) -> Result<Self, ParseError> {
        if meta {
            Ok(Some(T::deserialise(&mut reader, inner_meta)?))
        } else {
            Ok(None)
        }
    }
}

impl<T: Deserialise<()>> Deserialise<bool> for Option<T> {
    fn deserialise<R: Read>(mut reader: R, meta: bool) -> Result<Self, ParseError> {
        if meta {
            Ok(Some(T::deserialise(&mut reader, ())?))
        } else {
            Ok(None)
        }
    }
}

impl Deserialise<()> for bool {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let val = reader.read_u8()?;
        let ret = if val == 1 {
            true
        } else if val == 0 {
            false
        } else {
            return Err(ParseError::InvalidBool);
        };
        Ok(ret)
    }
}

impl Deserialise<()> for u8 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_u8()?;
        Ok(ret)
    }
}

impl Deserialise<()> for i8 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_i8()?;
        Ok(ret)
    }
}

impl Deserialise<()> for u16 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_u16::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for i16 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_i16::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for u32 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_u32::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for i32 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_i32::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for u64 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_u64::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for i64 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_i64::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for u128 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_u128::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for i128 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_i128::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for f32 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_f32::<BE>()?;
        Ok(ret)
    }
}

impl Deserialise<()> for f64 {
    fn deserialise<R: Read>(mut reader: R, _meta: ()) -> Result<Self, ParseError> {
        let ret = reader.read_f64::<BE>()?;
        Ok(ret)
    }
}