rust_mc_proto 0.1.19

lightweight minecraft protocol support in pure rust
Documentation
use crate::ProtocolError;
use std::{io::Read, usize};
use uuid::Uuid;

/// Packet data reader trait
pub trait DataReader {
    /// Read bytes
    fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, ProtocolError>;

    /// Read byte
    fn read_byte(&mut self) -> Result<u8, ProtocolError> {
        Ok(self.read_bytes(1)?[0])
    }
    /// Read String
    fn read_string(&mut self) -> Result<String, ProtocolError> {
        let size = self.read_usize_varint()?;
        match String::from_utf8(self.read_bytes(size)?) {
            Ok(i) => Ok(i),
            Err(_) => Err(ProtocolError::StringParseError),
        }
    }
    /// Read Signed byte as i8
    fn read_signed_byte(&mut self) -> Result<i8, ProtocolError> {
        Ok(self.read_byte()? as i8)
    }
    /// Read Unsigned Short as u16
    fn read_unsigned_short(&mut self) -> Result<u16, ProtocolError> {
        self.read_bytes(2)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| u16::from_be_bytes(o))
    }
    /// Read Boolean
    fn read_boolean(&mut self) -> Result<bool, ProtocolError> {
        self.read_byte().map(|o| o == 0x01)
    }
    /// Read Short as i16
    fn read_short(&mut self) -> Result<i16, ProtocolError> {
        self.read_bytes(2)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| i16::from_be_bytes(o))
    }
    /// Read Long as i64
    fn read_long(&mut self) -> Result<i64, ProtocolError> {
        self.read_bytes(8)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| i64::from_be_bytes(o))
    }
    /// Read Float as f32
    fn read_float(&mut self) -> Result<f32, ProtocolError> {
        self.read_bytes(4)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| f32::from_be_bytes(o))
    }
    /// Read Double as f64
    fn read_double(&mut self) -> Result<f64, ProtocolError> {
        self.read_bytes(8)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| f64::from_be_bytes(o))
    }
    /// Read Int as i32
    fn read_int(&mut self) -> Result<i32, ProtocolError> {
        self.read_bytes(4)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| i32::from_be_bytes(o))
    }
    /// Read UUID
    fn read_uuid(&mut self) -> Result<Uuid, ProtocolError> {
        self.read_bytes(16)
            .and_then(|o| o.try_into().map_err(|_| ProtocolError::ReadError))
            .map(|o| Uuid::from_bytes(o))
    }

    /// Read VarInt as u8
    fn read_u8_varint(&mut self) -> Result<u8, ProtocolError> {
        TryInto::<u8>::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarInt as u16
    fn read_u16_varint(&mut self) -> Result<u16, ProtocolError> {
        TryInto::<u16>::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarInt as u32
    /// 
    /// Returns error if the value is greater than i32::MAX
    fn read_u32_varint(&mut self) -> Result<u32, ProtocolError> {
        let val = self.read_varint()?;
        if val < 0 { return Err(ProtocolError::VarIntError); }
        TryInto::<u32>::try_into(val).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarInt as usize
    fn read_usize_varint(&mut self) -> Result<usize, ProtocolError> {
        Ok(TryInto::<usize>::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)?)
    }
    /// Read VarInt as i8
    fn read_i8_varint(&mut self) -> Result<i8, ProtocolError> {
        TryInto::<i8>::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarInt as i16
    fn read_i16_varint(&mut self,) -> Result<i16, ProtocolError> {
        TryInto::<i16>::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarInt as i32
    /// 
    /// *Use [read_varint](DataReader::read_varint) instead*
    fn read_i32_varint(&mut self) -> Result<i32, ProtocolError> {
        self.read_varint()
    }
    /// Read VarInt as isize
    fn read_isize_varint(&mut self) -> Result<isize, ProtocolError> {
        Ok(TryInto::<isize>::try_into(self.read_varint()?).map_err(|_| ProtocolError::VarIntError)?)
    }

    /// Read VarLong as u8
    fn read_u8_varlong(&mut self) -> Result<u8, ProtocolError> {
        TryInto::<u8>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as u16
    fn read_u16_varlong(&mut self) -> Result<u16, ProtocolError> {
        TryInto::<u16>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as u32
    fn read_u32_varlong(&mut self) -> Result<u32, ProtocolError> {
        TryInto::<u32>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as usize
    ///
    /// Returns error if the value is greater than i64::MAX
    fn read_usize_varlong(&mut self) -> Result<usize, ProtocolError> {
        let val = TryInto::<usize>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)?;
        if val as u64 > i64::MAX as u64 { return Err(ProtocolError::VarIntError); }
        Ok(val)
    }
    /// Read VarLong as u64
    ///
    /// Returns error if the value is greater than i64::MAX
    fn read_u64_varlong(&mut self) -> Result<u64, ProtocolError> {
        let val = self.read_varlong()?;
        if val < 0 { return Err(ProtocolError::VarIntError); }
        TryInto::<u64>::try_into(val).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as i8
    fn read_i8_varlong(&mut self) -> Result<i8, ProtocolError> {
        TryInto::<i8>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as i16
    fn read_i16_varlong(&mut self) -> Result<i16, ProtocolError> {
        TryInto::<i16>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as i32
    fn read_i32_varlong(&mut self) -> Result<i32, ProtocolError> {
        TryInto::<i32>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)
    }
    /// Read VarLong as isize
    fn read_isize_varlong(&mut self) -> Result<isize, ProtocolError> {
        Ok(TryInto::<isize>::try_into(self.read_varlong()?).map_err(|_| ProtocolError::VarIntError)?)
    }
    /// Read VarLong as i64
    ///
    /// *Use [read_varlong](DataReader::read_varlong) instead*
    fn read_i64_varlong(&mut self) -> Result<i64, ProtocolError> {
        self.read_varlong()
    }

    /// Read VarInt as u8 with size in bytes (value, size)
    fn read_u8_varint_size(&mut self) -> Result<(u8, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        Ok((TryInto::<u8>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarInt as u16 with size in bytes (value, size)
    fn read_u16_varint_size(&mut self) -> Result<(u16, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        Ok((TryInto::<u16>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarInt as u32 with size in bytes (value, size)
    /// 
    /// Returns error if the value is greater than i32::MAX
    fn read_u32_varint_size(&mut self) -> Result<(u32, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        if val < 0 { return Err(ProtocolError::VarIntError); }
        Ok((TryInto::<u32>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarInt as usize with size in bytes (value, size)
    fn read_usize_varint_size(&mut self) -> Result<(usize, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        Ok((TryInto::<usize>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarInt as i8 with size in bytes (value, size)
    fn read_i8_varint_size(&mut self) -> Result<(i8, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        Ok((TryInto::<i8>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarInt as i16 with size in bytes (value, size)
    fn read_i16_varint_size(&mut self,) -> Result<(i16, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        Ok((TryInto::<i16>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarInt as i32 with size in bytes (value, size)
    /// 
    /// *Use [read_varint_size](DataReader::read_varint_size) instead*
    fn read_i32_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> {
        self.read_varint_size()
    }
    /// Read VarInt as isize with size in bytes (value, size)
    fn read_isize_varint_size(&mut self) -> Result<(isize, usize), ProtocolError> {
        let (val, size) = self.read_varint_size()?;
        Ok((TryInto::<isize>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }

    /// Read VarLong as u8 with size in bytes (value, size)
    fn read_u8_varlong_size(&mut self) -> Result<(u8, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<u8>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as u16 with size in bytes (value, size)
    fn read_u16_varlong_size(&mut self) -> Result<(u16, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<u16>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as u32 with size in bytes (value, size)
    fn read_u32_varlong_size(&mut self) -> Result<(u32, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<u32>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as usize with size in bytes (value, size)
    ///
    /// Returns error if the value is greater than i64::MAX
    fn read_usize_varlong_size(&mut self) -> Result<(usize, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        let val = TryInto::<usize>::try_into(val).map_err(|_| ProtocolError::VarIntError)?;
        if val as u64 > i64::MAX as u64 { return Err(ProtocolError::VarIntError); }
        Ok((val, size))
    }
    /// Read VarLong as u64 with size in bytes (value, size)
    ///
    /// Returns error if the value is greater than i64::MAX
    fn read_u64_varlong_size(&mut self) -> Result<(u64, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        if val < 0 { return Err(ProtocolError::VarIntError); }
        Ok((TryInto::<u64>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as i8 with size in bytes (value, size)
    fn read_i8_varlong_size(&mut self) -> Result<(i8, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<i8>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as i16 with size in bytes (value, size)
    fn read_i16_varlong_size(&mut self) -> Result<(i16, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<i16>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as i32 with size in bytes (value, size)
    fn read_i32_varlong_size(&mut self) -> Result<(i32, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<i32>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as isize with size in bytes (value, size)
    fn read_isize_varlong_size(&mut self) -> Result<(isize, usize), ProtocolError> {
        let (val, size) = self.read_varlong_size()?;
        Ok((TryInto::<isize>::try_into(val).map_err(|_| ProtocolError::VarIntError)?, size))
    }
    /// Read VarLong as i64 with size in bytes (value, size)
    ///
    /// *Use [read_varlong_size](DataReader::read_varlong_size) instead*
    fn read_i64_varlong_size(&mut self) -> Result<(i64, usize), ProtocolError> {
        self.read_varlong_size()
    }

    /// Read VarInt as i32 with size in bytes (value, size)
    fn read_varint_size(&mut self) -> Result<(i32, usize), ProtocolError> {
        let mut value: u32 = 0;
        let mut position: u32 = 0;
        let mut size = 0;

        loop {
            let byte = self.read_byte()?;
            value |= TryInto::<u32>::try_into(byte & 0x7F).map_err(|_| ProtocolError::VarIntError)? << position;

            size += 1;

            if (byte & 0x80) == 0 {
                break;
            }

            position += 7;
        }

        Ok((value as i32, size))
    }
    /// Read VarLong as i64 with size in bytes (value, size)
    fn read_varlong_size(&mut self) -> Result<(i64, usize), ProtocolError> {
        let mut value: u64 = 0;
        let mut position: u32 = 0;
        let mut size = 0;

        loop {
            let byte = self.read_byte()?;
            value |= TryInto::<u64>::try_into(byte & 0x7F).map_err(|_| ProtocolError::VarIntError)? << position;

            size += 1;

            if (byte & 0x80) == 0 {
                break;
            }

            position += 7;
        }

        Ok((value as i64, size))
    }

    /// Read VarInt as i32
    fn read_varint(&mut self) -> Result<i32, ProtocolError> {
        self.read_varint_size().map(|o| o.0)
    }
    /// Read VarLong as i64
    fn read_varlong(&mut self) -> Result<i64, ProtocolError> {
        self.read_varlong_size().map(|o| o.0)
    }
}

impl<R: Read> DataReader for R {
    fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, ProtocolError> {
        let mut buf = vec![0; size];
        match self.read(&mut buf) {
            Ok(i) => if i == size {
                Ok(buf)
            } else if i == 0 {
                Err(ProtocolError::ConnectionClosedError)
            } else {
                buf.truncate(i);
                buf.append(&mut self.read_bytes(size-i)?);
                Ok(buf)
            },
            Err(_) => Err(ProtocolError::ReadError),
        }
    }
}