use alloc::{string::String, vec::Vec, fmt};
use crate::utils::*;
use crate::uuid::UUID4;
use crate::*;
pub use super::chat::*;
#[cfg(all(test, feature = "std"))]
use crate::protocol::TestRandom;
use crate::byte_order::{ProtoByteOrder, ByteOrder};
impl Serialize for bool {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_byte(if *self { 1 } else { 0 })
}
}
impl Deserialize for bool {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
ProtoByteOrder::read_ubyte(data)?.try_map(move |b| match b {
0x00 => Ok(false),
0x01 => Ok(true),
other => Err(DeserializeErr::InvalidBool(other)),
})
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for bool {
fn test_gen_random() -> Self {
rand::random()
}
}
macro_rules! def_primitive {
($nam: ty, $read: ident, $write: ident) => {
impl Serialize for $nam {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
let data = ProtoByteOrder::$write(*self);
to.serialize_bytes(&data)
}
}
impl Deserialize for $nam {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
ProtoByteOrder::$read(data)
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for $nam {
fn test_gen_random() -> Self {
rand::random()
}
}
};
}
def_primitive!(u8, read_ubyte, write_ubyte);
def_primitive!(i8, read_byte, write_byte);
def_primitive!(u16, read_ushort, write_ushort);
def_primitive!(i16, read_short, write_short);
def_primitive!(u32, read_uint, write_uint);
def_primitive!(i32, read_int, write_int);
def_primitive!(u64, read_ulong, write_ulong);
def_primitive!(i64, read_long, write_long);
def_primitive!(u128, read_u2long, write_u2long);
def_primitive!(i128, read_2long, write_2long);
def_primitive!(f32, read_float, write_float);
def_primitive!(f64, read_double, write_double);
macro_rules! def_varnum {
($nam: ident, $data_type: ty, $working_type: ty, $max_bytes: literal) => {
#[derive(Copy, Clone, PartialOrd, PartialEq, Default, Hash, Ord, Eq)]
pub struct $nam(pub $data_type);
impl Serialize for $nam {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
let mut out = [0u8; $max_bytes];
let mut v: $working_type = self.0 as $working_type;
let mut byte_idx = 0;
let mut has_more = true;
while has_more {
if byte_idx == out.len() {
panic!("tried to write too much data for {}", stringify!($nam));
}
let mut v_byte = (v & 0x7F) as u8;
v >>= 7;
has_more = v != 0;
if has_more {
v_byte |= 0x80;
}
out[byte_idx] = v_byte;
byte_idx += 1;
}
to.serialize_bytes(&out[..byte_idx])
}
}
impl Deserialize for $nam {
fn mc_deserialize(orig_data: &[u8]) -> DeserializeResult<Self> {
let mut data = orig_data;
let mut v: $working_type = 0;
let mut bit_place: usize = 0;
let mut i: usize = 0;
let mut has_more = true;
while has_more {
if i == $max_bytes {
return DeserializeErr::VarNumTooLong(Vec::from(&orig_data[..i])).into();
}
let Deserialized { value: byte, data: rest } = ProtoByteOrder::read_ubyte(data)?;
data = rest;
has_more = byte & 0x80 != 0;
v |= ((byte as $working_type) & 0x7F) << bit_place;
bit_place += 7;
i += 1;
}
Deserialized::ok(Self(v as $data_type), data)
}
}
impl From<$data_type> for $nam {
fn from(other: $data_type) -> Self {
Self(other)
}
}
impl From<$nam> for $data_type {
fn from(other: $nam) -> Self {
other.0
}
}
impl core::ops::Deref for $nam {
type Target = $data_type;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Display for $nam {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl fmt::Debug for $nam {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(stringify!($nam))?;
f.write_str("(")?;
write!(f, "{}", self.0)?;
f.write_str(")")?;
Ok(())
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for $nam {
fn test_gen_random() -> Self {
let out: $data_type = rand::random();
Self(out)
}
}
}
}
def_varnum!(VarInt, i32, u32, 5);
def_varnum!(VarLong, i64, u64, 10);
impl Serialize for String {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_other(&VarInt(self.len() as i32))?;
to.serialize_bytes(self.as_bytes())
}
}
impl Deserialize for String {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
VarInt::mc_deserialize(data)?.and_then(move |length, rest| {
if length.0 < 0 {
Err(DeserializeErr::NegativeLength(length))
} else {
take(length.0 as usize, rest)?.try_map(move |taken| {
String::from_utf8(taken.to_vec()).map_err(DeserializeErr::BadStringEncoding)
})
}
})
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for String {
fn test_gen_random() -> Self {
let raw_len: u8 = rand::random();
let len = raw_len as usize;
let mut out = String::with_capacity(len);
for _ in 0..len {
let c_idx: u8 = rand::random::<u8>() % 36;
let c = if c_idx <= 10 {
(48 + c_idx) as char
} else {
((c_idx - 10) + 65) as char
};
out.push(c)
}
out
}
}
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub struct IntPosition {
pub x: i32,
pub y: i16,
pub z: i32,
}
impl Serialize for IntPosition {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
let x_raw = if self.x < 0 {
(self.x + 0x2000000) as u64 | 0x2000000
} else {
self.x as u64
} & 0x3FFFFFF;
let z_raw = if self.z < 0 {
(self.z + 0x2000000) as u64 | 0x2000000
} else {
self.z as u64
} & 0x3FFFFFF;
let y_raw = if self.y < 0 {
(self.y + 0x800) as u64 | 0x800
} else {
self.y as u64
} & 0xFFF;
let data = ProtoByteOrder::write_ulong(((x_raw << 38) | (z_raw << 12) | y_raw) as u64);
to.serialize_bytes(&data)
}
}
impl Deserialize for IntPosition {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
let Deserialized { value: raw, data } = ProtoByteOrder::read_ulong(data)?;
let mut x = ((raw >> 38) as u32) & 0x3FFFFFF;
let mut z = ((raw >> 12) & 0x3FFFFFF) as u32;
let mut y = ((raw & 0xFFF) as u16) & 0xFFF;
if (x & 0x2000000) != 0 {
x = (((x & 0x1FFFFFF) as i32) - 0x2000000) as u32;
}
if (y & 0x800) != 0 {
y = (((y & 0x7FF) as i16) - 0x800) as u16;
}
if (z & 0x2000000) != 0 {
z = (((z & 0x1FFFFFF) as i32) - 0x2000000) as u32;
}
Deserialized::ok(
IntPosition {
x: x as i32,
y: y as i16,
z: z as i32,
},
data,
)
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for IntPosition {
fn test_gen_random() -> Self {
let x: i32 = ((rand::random::<u32>() % (1 << 26)) as i32) - (1 << 25);
let z: i32 = ((rand::random::<u32>() % (1 << 26)) as i32) - (1 << 25);
let y: i16 = ((rand::random::<u16>() % (1 << 12)) as i16) - (1 << 11);
Self { x, y, z }
}
}
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
pub struct Angle {
pub value: u8,
}
impl Serialize for Angle {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_byte(self.value)
}
}
impl Deserialize for Angle {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
Ok(ProtoByteOrder::read_ubyte(data)?.map(move |b| Angle { value: b }))
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for Angle {
fn test_gen_random() -> Self {
Self {
value: rand::random(),
}
}
}
impl Serialize for UUID4 {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
let bytes = ProtoByteOrder::write_u2long(self.to_u128());
to.serialize_bytes(&bytes[..])
}
}
impl Deserialize for UUID4 {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
Ok(ProtoByteOrder::read_u2long(data)?.map(move |raw| UUID4::from(raw)))
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for UUID4 {
fn test_gen_random() -> Self {
UUID4::random()
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct NamedNbtTag {
pub root: nbt::NamedTag,
}
impl Serialize for NamedNbtTag {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
let bytes = self.root.bytes();
to.serialize_bytes(bytes.as_slice())
}
}
impl Deserialize for NamedNbtTag {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
Ok(
nbt::NamedTag::root_compound_tag_from_bytes(data)?
.map(move |root| NamedNbtTag { root }),
)
}
}
impl From<nbt::NamedTag> for NamedNbtTag {
fn from(root: nbt::NamedTag) -> Self {
Self { root }
}
}
impl Into<nbt::NamedTag> for NamedNbtTag {
fn into(self) -> nbt::NamedTag {
self.root
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for NamedNbtTag {
fn test_gen_random() -> Self {
Self {
root: nbt::NamedTag::test_gen_random(),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct FixedInt {
raw: i32,
}
impl Serialize for FixedInt {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_other(&self.raw)
}
}
impl Deserialize for FixedInt {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
Ok(i32::mc_deserialize(data)?.map(move |raw| FixedInt { raw }))
}
}
impl FixedInt {
pub fn new(data: f64, fractional_bytes: usize) -> Self {
Self {
raw: (data * ((1 << fractional_bytes) as f64)) as i32,
}
}
pub fn into_float(self, fractional_bytes: usize) -> f64 {
(self.raw as f64) / ((1 << fractional_bytes) as f64)
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for FixedInt {
fn test_gen_random() -> Self {
FixedInt::new(f64::test_gen_random(), 16)
}
}
#[derive(Default)]
pub struct BytesSerializer {
data: Vec<u8>,
}
impl Serializer for BytesSerializer {
fn serialize_bytes(&mut self, data: &[u8]) -> SerializeResult {
self.data.extend_from_slice(data);
Ok(())
}
}
impl BytesSerializer {
pub fn with_capacity(cap: usize) -> Self {
BytesSerializer {
data: Vec::with_capacity(cap),
}
}
pub fn into_bytes(self) -> Vec<u8> {
self.data
}
}
impl<T> Serialize for Option<T>
where
T: Serialize,
{
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
match self {
Some(value) => {
to.serialize_other(&true)?;
to.serialize_other(value)
}
None => to.serialize_other(&false),
}
}
}
impl<T> Deserialize for Option<T>
where
T: Deserialize,
{
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
bool::mc_deserialize(data)?.and_then(move |is_present, data| {
if is_present {
Ok(T::mc_deserialize(data)?.map(move |component| Some(component)))
} else {
Deserialized::ok(None, data)
}
})
}
}
#[cfg(all(test, feature = "std"))]
impl<T> TestRandom for Option<T>
where
T: TestRandom,
{
fn test_gen_random() -> Self {
let is_present: bool = rand::random();
if is_present {
Some(T::test_gen_random())
} else {
None
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct ItemStack {
pub item_id: VarInt,
pub item_count: i8,
pub nbt: Option<nbt::NamedTag>,
}
impl Serialize for ItemStack {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_other(&self.item_id)?;
to.serialize_other(&self.item_count)?;
match self.nbt.as_ref() {
Some(nbt) => to.serialize_bytes(nbt.bytes().as_slice()),
None => to.serialize_byte(nbt::Tag::End.id()),
}
}
}
impl Deserialize for ItemStack {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
let Deserialized { value: item_id, data } = VarInt::mc_deserialize(data)?;
let Deserialized { value: item_count, data } = i8::mc_deserialize(data)?;
if data.is_empty() {
return Err(DeserializeErr::Eof);
}
let id = data[0];
let rest = &data[1..];
Ok(match id {
0x00 => Deserialized {
value: None,
data: rest,
},
_ => nbt::read_named_tag(data)?.map(move |tag| Some(tag)),
}.map(move |nbt| Self {
item_id,
item_count,
nbt,
}))
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for ItemStack {
fn test_gen_random() -> Self {
let item_id = VarInt::test_gen_random();
let item_count = i8::test_gen_random() % 65;
let nbt = <Option<nbt::NamedTag>>::test_gen_random();
Self {
item_id,
item_count,
nbt,
}
}
}
pub type Slot = Option<ItemStack>;
macro_rules! def_vector_type {
($name: ident, $($fnam: ident),+) => {
crate::as_item! {
pub struct $name<T> {
$(pub $fnam: T),+
}
}
impl<T> Serialize for $name<T> where T: Serialize {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
$(
to.serialize_other(&self.$fnam)?;
)+
Ok(())
}
}
impl<T> Deserialize for $name<T> where T: Deserialize {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
$(let Deserialized { value: $fnam, data } = T::mc_deserialize(data)?;)+
Deserialized::ok(Self { $($fnam),+ }, data)
}
}
#[cfg(all(test, feature = "std"))]
impl<T> TestRandom for $name<T> where T: TestRandom {
fn test_gen_random() -> Self {
Self {
$($fnam: T::test_gen_random(),)+
}
}
}
impl<T> Clone for $name<T> where T: Clone {
fn clone(&self) -> Self {
Self {
$($fnam: self.$fnam.clone(),)+
}
}
}
impl<T> Copy for $name<T> where T: Copy {}
impl<T, Rhs> PartialEq<$name<Rhs>> for $name<T> where T: PartialEq<Rhs> {
fn eq(&self, other: &$name<Rhs>) -> bool {
$(self.$fnam.eq(&other.$fnam)) && +
}
fn ne(&self, other: &$name<Rhs>) -> bool {
$(self.$fnam.ne(&other.$fnam)) || +
}
}
impl<T> core::hash::Hash for $name<T> where T: core::hash::Hash {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
$(self.$fnam.hash(state);)+
}
}
impl<T> fmt::Debug for $name<T> where T: fmt::Debug {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(stringify!($name))?;
f.write_str("( ")?;
$(
f.write_str(stringify!($fnam))?;
f.write_str("=")?;
self.$fnam.fmt(f)?;
f.write_str(" ")?;
)+
f.write_str(")")?;
Ok(())
}
}
impl<T> fmt::Display for $name<T> where T: fmt::Display {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(stringify!($name))?;
f.write_str("( ")?;
$(
f.write_str(stringify!($fnam))?;
f.write_str("=")?;
self.$fnam.fmt(f)?;
f.write_str(" ")?;
)+
f.write_str(")")?;
Ok(())
}
}
impl<T> From<$name<T>> for ($(crate::instead_of_ident!($fnam, T)),+) {
fn from(other: $name<T>) -> Self {
($(other.$fnam),+)
}
}
impl<'a, T> From<&'a $name<T>> for ($(&'a crate::instead_of_ident!($fnam, T)),+) {
fn from(other: &'a $name<T>) -> Self {
($(&other.$fnam),+)
}
}
impl<'a, T> From<&'a $name<T>> for ($(crate::instead_of_ident!($fnam, T)),+) where T: Clone {
fn from(other: &'a $name<T>) -> Self {
($(other.$fnam.clone()),+)
}
}
impl<T> From<($(crate::instead_of_ident!($fnam, T)),+)> for $name<T> {
fn from(other: ($(crate::instead_of_ident!($fnam, T)),+)) -> Self {
let ($($fnam),+) = other;
Self { $($fnam),+ }
}
}
impl<'a, T> From<&'a ($(crate::instead_of_ident!($fnam, T)),+)> for $name<T> where T: Clone {
fn from(other: &'a ($(crate::instead_of_ident!($fnam, T)),+)) -> Self {
let ($($fnam),+) = other;
$(let $fnam = $fnam.clone();)+
Self { $($fnam),+ }
}
}
impl<'a, T> From<($(&'a crate::instead_of_ident!($fnam, T)),+)> for $name<T> where T: Clone {
fn from(other: ($(&'a crate::instead_of_ident!($fnam, T)),+)) -> Self {
let ($($fnam),+) = other;
$(let $fnam = $fnam.clone();)+
Self { $($fnam),+ }
}
}
impl<T> $name<T> {
pub fn from_other<O>(other: O) -> Self where O: Into<($(crate::instead_of_ident!($fnam, T)),+)> {
let ($($fnam),+) = other.into();
Self { $($fnam,)+ }
}
pub fn as_other<O>(&self) -> O where O: From<($(crate::instead_of_ident!($fnam, T)),+)>, T: Clone {
O::from(self.into())
}
pub fn into_other<O>(self) -> O where O: From<($(crate::instead_of_ident!($fnam, T)),+)> {
O::from(self.into())
}
}
};
}
def_vector_type!(Vec3, x, y, z);
def_vector_type!(Vec2, x, y);
def_vector_type!(ChunkPosition, x, z);
pub type TopDownPosition<T> = ChunkPosition<T>;
def_vector_type!(EntityRotation, yaw, pitch);
proto_struct!(EntityLocation<P, R> {
position: Vec3<P>,
rotation: EntityRotation<R>
});
#[derive(Clone, Debug, PartialEq)]
pub struct CountedArray<E, C> {
data: Vec<E>,
_counter_type: core::marker::PhantomData<C>,
}
pub trait ArrayCounter: Serialize + Deserialize {
fn as_count(&self) -> usize;
fn from_count(count: usize) -> Self;
}
impl<E, C> Serialize for CountedArray<E, C> where E: Serialize, C: ArrayCounter {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
let count = C::from_count(self.data.len());
to.serialize_other(&count)?;
for elem in &self.data {
to.serialize_other(elem)?;
}
Ok(())
}
}
impl<E, C> Deserialize for CountedArray<E, C> where E: Deserialize, C: ArrayCounter {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
let Deserialized { value: count, mut data } = C::mc_deserialize(data)?;
let count = count.as_count();
let mut elems = Vec::with_capacity(count);
for _ in 0..count {
let Deserialized { value: elem, data: rest } = E::mc_deserialize(data)?;
data = rest;
elems.push(elem);
}
Deserialized::ok(Self {
data: elems,
_counter_type: core::marker::PhantomData,
}, data)
}
}
impl<E, C> core::ops::Deref for CountedArray<E, C> where C: ArrayCounter {
type Target = Vec<E>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl<E, C> core::ops::DerefMut for CountedArray<E, C> where C: ArrayCounter {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl<E, C> From<CountedArray<E, C>> for Vec<E> where C: ArrayCounter {
fn from(other: CountedArray<E, C>) -> Self {
other.data
}
}
impl<E, C> From<Vec<E>> for CountedArray<E, C> where C: ArrayCounter {
fn from(data: Vec<E>) -> Self {
Self {
data,
_counter_type: core::marker::PhantomData,
}
}
}
#[cfg(all(test, feature = "std"))]
impl<E, C> TestRandom for CountedArray<E, C>
where E: TestRandom, C: ArrayCounter
{
fn test_gen_random() -> Self {
let elem_count: usize = rand::random::<usize>() % 32;
let mut out = Vec::with_capacity(elem_count);
for _ in 0..elem_count {
out.push(E::test_gen_random());
}
out.into()
}
}
impl ArrayCounter for VarInt {
fn as_count(&self) -> usize {
self.0 as usize
}
fn from_count(count: usize) -> Self {
Self(count as i32)
}
}
impl ArrayCounter for i16 {
fn as_count(&self) -> usize {
(*self) as usize
}
fn from_count(count: usize) -> Self {
count as i16
}
}
impl ArrayCounter for i32 {
fn as_count(&self) -> usize {
(*self) as usize
}
fn from_count(count: usize) -> Self {
count as i32
}
}
impl ArrayCounter for i8 {
fn as_count(&self) -> usize {
(*self) as usize
}
fn from_count(count: usize) -> Self {
count as i8
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct RemainingBytes {
pub data: Vec<u8>,
}
impl Serialize for RemainingBytes {
fn mc_serialize<S: Serializer>(&self, to: &mut S) -> SerializeResult {
to.serialize_bytes(self.data.as_slice())
}
}
impl Deserialize for RemainingBytes {
fn mc_deserialize(data: &[u8]) -> DeserializeResult<'_, Self> {
Deserialized::ok(
RemainingBytes {
data: Vec::from(data),
},
&[],
)
}
}
impl Into<Vec<u8>> for RemainingBytes {
fn into(self) -> Vec<u8> {
self.data
}
}
impl From<Vec<u8>> for RemainingBytes {
fn from(data: Vec<u8>) -> Self {
Self { data }
}
}
impl core::ops::Deref for RemainingBytes {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl core::ops::DerefMut for RemainingBytes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
#[cfg(all(test, feature = "std"))]
impl TestRandom for RemainingBytes {
fn test_gen_random() -> Self {
let size: usize = rand::random::<usize>() % 256;
let mut out = Vec::with_capacity(size);
for _ in 0..size {
out.push(rand::random());
}
Self { data: out }
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::fmt::Debug;
use alloc::borrow::ToOwned;
#[test]
fn test_bool() {
test_type(true);
test_type(false);
}
#[test]
fn test_signed_byte() {
test_type(0i8);
test_type(127i8);
test_type(-15i8);
}
#[test]
fn test_unsigned_byte() {
test_type(0u8);
test_type(128u8);
test_type(255u8);
}
#[test]
fn test_signed_short() {
test_type(0i16);
test_type(-88i16);
test_type(25521i16);
}
#[test]
fn test_unsigned_short() {
test_type(0u16);
test_type(1723u16);
test_type(65534u16);
}
#[test]
fn test_signed_int() {
test_type(0i32);
test_type(123127i32);
test_type(-171238i32);
test_type(2147483647i32);
}
#[test]
fn test_signed_long() {
test_type(0i64);
test_type(123127i64);
test_type(-12123127i64);
test_type(2147483647i64);
test_type(-10170482028482i64);
}
#[test]
fn test_float() {
test_type(0.2313f32);
test_type(0f32);
test_type(123123213f32);
test_type(-123123f32);
}
#[test]
fn test_double() {
test_type(0.2313f64);
test_type(0f64);
test_type(123123213f64);
test_type(-123123f64);
}
#[test]
fn test_var_int() {
test_type(VarInt(0));
test_type(VarInt(1231231));
test_type(VarInt(2147483647));
test_type(VarInt(-2147483648));
test_type(VarInt(-1));
test_type(VarInt(-1001237));
}
#[test]
fn test_var_long() {
test_type(VarLong(0));
test_type(VarLong(1231231));
test_type(VarLong(12312319123));
test_type(VarLong(9223372036854775807));
test_type(VarLong(-1));
test_type(VarLong(-12312319123));
test_type(VarLong(-9223372036854775808));
test_type(VarLong(-1001237));
}
#[test]
fn test_string() {
test_type(String::from("hello my name is joey 123"));
test_type(String::from(""));
test_type(String::from("AAAA"));
test_type(String::from("hello my name is joey 123").repeat(1000));
}
#[test]
fn test_nbt() {
test_type(NamedNbtTag {
root: nbt::Tag::Compound(alloc::vec![
nbt::Tag::String("test 123".to_owned()).with_name("abc 123")
])
.with_name("root"),
})
}
#[test]
fn test_int_position() {
test_type(IntPosition {
x: 12312,
y: -32,
z: 321312,
});
test_type(IntPosition {
x: 12312,
y: -32,
z: -321312,
});
test_type(IntPosition {
x: -12312,
y: -32,
z: -321312,
});
test_type(IntPosition {
x: -12312,
y: 32,
z: 321312,
});
test_type(IntPosition { x: 0, y: 0, z: 0 });
test_type(IntPosition {
x: 48,
y: 232,
z: 12,
});
test_type(IntPosition {
x: 33554431,
y: 2047,
z: 33554431,
});
test_type(IntPosition {
x: -33554432,
y: -2048,
z: -33554432,
});
test_type(IntPosition {
x: 3,
y: 0,
z: 110655,
});
}
#[cfg(feature = "std")]
#[test]
fn test_uuid() {
for _ in 0..5 {
test_type(UUID4::random());
}
}
#[test]
fn test_angle() {
test_type(Angle { value: 0 });
test_type(Angle { value: 24 });
test_type(Angle { value: 255 });
test_type(Angle { value: 8 });
}
fn test_type<S: Serialize + Deserialize + PartialEq + Debug>(value: S) {
let bytes = {
let mut test = BytesSerializer::default();
value
.mc_serialize(&mut test)
.expect("serialization should succeed");
test.into_bytes()
};
let deserialized =
S::mc_deserialize(bytes.as_slice()).expect("deserialization should succeed");
assert!(deserialized.data.is_empty());
assert_eq!(
deserialized.value, value,
"deserialized value == serialized value"
);
let re_serialized = {
let mut test = BytesSerializer::default();
deserialized
.value
.mc_serialize(&mut test)
.expect("serialization should succeed");
test.into_bytes()
};
assert_eq!(
re_serialized, bytes,
"serialized value == original serialized bytes"
);
}
}