use std::{collections::HashMap, io::Read, iter::FromIterator};
use crate::{
borrow, from_bytes, from_reader,
test::{resources::CHUNK_RAW_WITH_ENTITIES, Single, Wrap},
to_bytes, ByteArray, IntArray, LongArray, Tag, Value,
};
use serde::{ser::SerializeMap, Deserialize, Serialize};
use serde_bytes::{ByteBuf, Bytes};
use super::{builder::Builder, resources};
#[test]
fn simple_byte() {
let v = Single { val: 123u8 };
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.byte("val", 123)
.end_compound()
.build();
assert_eq!(expected, bs);
}
#[test]
fn simple_numbers() {
#[derive(Serialize)]
struct V {
i8: i8,
i16: i16,
i32: i32,
i64: i64,
u8: u8,
u16: u16,
u32: u32,
u64: u64,
f32: f32,
f64: f64,
}
let v = V {
i8: i8::MAX,
i16: i16::MAX,
i32: i32::MAX,
i64: i64::MAX,
u8: u8::MAX,
u16: u16::MAX,
u32: u32::MAX,
u64: u64::MAX,
f32: f32::MAX,
f64: f64::MAX,
};
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.byte("i8", i8::MAX)
.short("i16", i16::MAX)
.int("i32", i32::MAX)
.long("i64", i64::MAX)
.byte("u8", u8::MAX as i8)
.short("u16", u16::MAX as i16)
.int("u32", u32::MAX as i32)
.long("u64", u64::MAX as i64)
.float("f32", f32::MAX)
.double("f64", f64::MAX)
.end_compound()
.build();
assert_eq!(expected, bs);
}
#[test]
fn serialize_i128() {
#[derive(Serialize)]
struct V {
max: u128,
min: i128,
zero: i128,
counting: u128,
}
let v = V {
max: u128::MAX,
min: i128::MIN,
zero: 0,
counting: 1 << 96 | 2 << 64 | 3 << 32 | 4,
};
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.int_array("max", &[u32::MAX as i32; 4])
.int_array("min", &[1 << 31, 0, 0, 0])
.int_array("zero", &[0; 4])
.int_array("counting", &[1, 2, 3, 4])
.tag(Tag::End)
.build();
assert_eq!(expected, bs);
}
#[test]
fn simple_string() {
let v = Single {
val: "hello".to_owned(),
};
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.string("val", "hello")
.end_compound()
.build();
assert_eq!(expected, bs);
}
#[test]
fn nested() {
let v = Single {
val: Single { val: 123 },
};
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.start_compound("val")
.int("val", 123)
.end_compound()
.end_compound()
.build();
assert_eq!(expected, bs);
}
#[test]
fn list_of_int() {
let v = Single { val: [1i32, 2, 3] };
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Int, 3)
.int_payload(1)
.int_payload(2)
.int_payload(3)
.end_compound()
.build();
assert_eq!(expected, bs);
}
#[test]
fn list_of_short() {
let v = Single { val: [1i16, 2, 3] };
let bs = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Short, 3)
.short_payload(1)
.short_payload(2)
.short_payload(3)
.end_compound()
.build();
assert_eq!(expected, bs);
}
#[test]
fn list_of_compounds() {
#[derive(Serialize)]
struct V {
list: [Single<i32>; 3],
}
let v = V {
list: [Single { val: 1 }, Single { val: 2 }, Single { val: 3 }],
};
let expected = Builder::new()
.start_compound("")
.start_list("list", Tag::Compound, 3)
.int("val", 1)
.end_compound()
.int("val", 2)
.end_compound()
.int("val", 3)
.end_compound()
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn list_of_list_of_bytes() {
#[derive(Serialize)]
struct V {
list: [[u8; 1]; 3],
}
let v = V {
list: [[1], [2], [3]],
};
let expected = Builder::new()
.start_compound("")
.start_list("list", Tag::List, 3) .start_anon_list(Tag::Byte, 1)
.byte_payload(1)
.start_anon_list(Tag::Byte, 1)
.byte_payload(2)
.start_anon_list(Tag::Byte, 1)
.byte_payload(3)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn list_of_list() {
#[derive(Serialize)]
struct V {
list: [[Single<i32>; 1]; 3],
}
let v = V {
list: [
[Single { val: 1 }],
[Single { val: 2 }],
[Single { val: 3 }],
],
};
let expected = Builder::new()
.start_compound("")
.start_list("list", Tag::List, 3)
.start_anon_list(Tag::Compound, 1)
.start_anon_compound()
.int("val", 1)
.end_anon_compound()
.start_anon_list(Tag::Compound, 1)
.start_anon_compound()
.int("val", 2)
.end_anon_compound()
.start_anon_list(Tag::Compound, 1)
.start_anon_compound()
.int("val", 3)
.end_anon_compound()
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn multiple_fields() {
#[derive(Serialize)]
struct V {
a: u8,
b: u16,
}
let v = V { a: 123, b: 1024 };
let payload = Builder::new()
.tag(Tag::Compound)
.name("")
.tag(Tag::Byte)
.name("a")
.byte_payload(123)
.tag(Tag::Short)
.name("b")
.short_payload(1024)
.tag(Tag::End)
.build();
let expected = to_bytes(&v).unwrap();
assert_eq!(expected, payload);
}
#[test]
fn serialize_str() {
let v = Single { val: "hello" };
let expected = Builder::new()
.start_compound("")
.string("val", "hello")
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn hashmap() {
let v = HashMap::<_, _>::from_iter([("a", 123), ("b", 234)]);
let expected1 = Builder::new()
.start_compound("")
.int("a", 123)
.int("b", 234)
.end_compound()
.build();
let expected2 = Builder::new()
.start_compound("")
.int("b", 234)
.int("a", 123)
.end_compound()
.build();
assert!(expected1 == to_bytes(&v).unwrap() || expected2 == to_bytes(&v).unwrap());
}
#[test]
fn vec() {
let v = Single {
val: vec![1, 2, 3, 4, 5],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Int, 5)
.int_payload(1)
.int_payload(2)
.int_payload(3)
.int_payload(4)
.int_payload(5)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn vec_in_vec() {
let v = Single {
val: vec![vec![Single { val: 123 }]],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::List, 1)
.start_anon_list(Tag::Compound, 1)
.int("val", 123)
.end_anon_compound()
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn optional() {
#[derive(Serialize)]
struct V<'a> {
opt1: Option<&'a str>,
opt2: Option<&'a str>,
}
let v = V {
opt1: Some("hello"),
opt2: None,
};
let expected = Builder::new()
.start_compound("")
.string("opt1", "hello")
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
let v = Single { val: [v] };
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Compound, 1)
.start_anon_compound()
.string("opt1", "hello")
.end_anon_compound()
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn newtype_struct() {
let v = Single { val: Wrap(123) };
let expected = Builder::new()
.start_compound("")
.int("val", 123)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn newtype_struct_list() {
let v = Single {
val: [Wrap(1), Wrap(2)],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Int, 2)
.int_payload(1)
.int_payload(2)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn nbt_byte_array() {
let v = Single {
val: ByteArray::new(vec![1, 2, 3]),
};
let expected = Builder::new()
.start_compound("")
.byte_array("val", &[1, 2, 3])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn nbt_int_array() {
let v = Single {
val: IntArray::new(vec![1, 2, 3]),
};
let expected = Builder::new()
.start_compound("")
.int_array("val", &[1, 2, 3])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn nbt_long_array() {
let v = Single {
val: LongArray::new(vec![1, 2, 3]),
};
let expected = Builder::new()
.start_compound("")
.long_array("val", &[1, 2, 3])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn value_hashmap() {
let v = Value::Compound(HashMap::from_iter([
("a".to_string(), Value::Int(123)),
("b".to_string(), Value::Byte(123)),
]));
let expected1 = Builder::new()
.start_compound("")
.byte("b", 123)
.int("a", 123)
.end_compound()
.build();
let expected2 = Builder::new()
.start_compound("")
.int("a", 123)
.byte("b", 123)
.end_compound()
.build();
assert!(expected1 == to_bytes(&v).unwrap() || expected2 == to_bytes(&v).unwrap());
}
#[test]
fn nbt_long_array_in_list() {
let v = Single {
val: [LongArray::new(vec![1, 2, 3]), LongArray::new(vec![4, 5, 6])],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::LongArray, 2)
.int_payload(3)
.long_array_payload(&[1, 2, 3])
.int_payload(3)
.long_array_payload(&[4, 5, 6])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn borrowed_nbt_byte_array_in_list() {
let v = Single {
val: [
borrow::ByteArray::new(&[1, 2, 3]),
borrow::ByteArray::new(&[4, 5, 6]),
],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::ByteArray, 2)
.int_payload(3)
.byte_array_payload(&[1, 2, 3])
.int_payload(3)
.byte_array_payload(&[4, 5, 6])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn borrowed_nbt_int_array_in_list() {
let v = Single {
val: [
borrow::IntArray::new(&[1, 2, 3]),
borrow::IntArray::new(&[4, 5, 6]),
],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::IntArray, 2)
.int_payload(3)
.int_array_payload(&[1, 2, 3])
.int_payload(3)
.int_array_payload(&[4, 5, 6])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn borrowed_nbt_long_array_in_list() {
let v = Single {
val: [
borrow::LongArray::new(&[1, 2, 3]),
borrow::LongArray::new(&[4, 5, 6]),
],
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::LongArray, 2)
.int_payload(3)
.long_array_payload(&[1, 2, 3])
.int_payload(3)
.long_array_payload(&[4, 5, 6])
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn unit_enum() {
#[derive(Serialize)]
#[allow(unused)]
enum Letter {
A,
B,
C,
}
let v = Single { val: Letter::A };
let expected = Builder::new()
.start_compound("")
.string("val", "A")
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn tuple_struct() {
#[derive(Serialize)]
struct Rgb(u8, u8, u8);
let v = Single { val: Rgb(1, 2, 3) };
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Byte, 3)
.byte_payload(1)
.byte_payload(2)
.byte_payload(3)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn enum_tuple_variant() {
#[derive(Serialize)]
enum Colour {
Rgb(u8, u8, u8),
}
let v = Single {
val: Colour::Rgb(1, 2, 3),
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Byte, 3)
.byte_payload(1)
.byte_payload(2)
.byte_payload(3)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn empty_list() {
let v = Single::<Vec<i32>> { val: vec![] };
let actual = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::End, 0)
.end_compound()
.build();
assert_eq!(expected, actual);
}
#[test]
#[ignore = "doesn't work yet"]
fn must_have_root() {
assert!(matches!(to_bytes(&123), Err(_)));
}
#[test]
fn list_of_empty_lists() {
let v = Single::<[[u32; 0]; 2]> { val: [[], []] };
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::List, 2)
.start_anon_list(Tag::End, 0)
.start_anon_list(Tag::End, 0)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn round_trip() {
let chunk: Value = from_bytes(CHUNK_RAW_WITH_ENTITIES).unwrap();
let bytes = to_bytes(&chunk).unwrap();
let roundtrip_chunk: Value = from_bytes(&bytes).unwrap();
assert_eq!(roundtrip_chunk, chunk);
}
#[test]
fn serialize_bytes() {
let v = Single {
val: serde_bytes::Bytes::new(&[1, 2, 3]),
};
let expected = Builder::new()
.start_compound("")
.start_list("val", Tag::Byte, 3)
.byte_payload(1)
.byte_payload(2)
.byte_payload(3)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn cesu_bytes() {
let symbol = "\u{10401}";
let modified_unicode_str = cesu8::to_java_cesu8(symbol);
#[derive(Serialize)]
struct V {
#[serde(rename = "\u{10401}")]
val: String,
}
let v = V {
val: symbol.to_string(),
};
let expected = Builder::new()
.start_compound("")
.tag(Tag::String)
.name(symbol)
.raw_str_len(modified_unicode_str.len())
.raw_bytes(&modified_unicode_str)
.end_compound()
.build();
assert_eq!(expected, to_bytes(&v).unwrap());
}
#[test]
fn bytes_as_fields() {
let mut map = HashMap::new();
map.insert(Bytes::new(b"hello"), "world");
let expected = Builder::new()
.start_compound("")
.string("hello", "world")
.end_compound()
.build();
assert_eq!(expected, to_bytes(&map).unwrap());
}
#[test]
fn basic_newtype_variant_enum() {
#[derive(Serialize, Debug, PartialEq)]
#[serde(untagged)]
enum Letter {
_A(u32),
B(String),
}
#[derive(Serialize, Debug)]
struct V {
letter: Letter,
}
let v = V {
letter: Letter::B("abc".to_owned()),
};
let expected = Builder::new()
.start_compound("")
.string("letter", "abc") .end_compound()
.build();
let actual = to_bytes(&v).unwrap();
assert_eq!(actual, expected);
}
#[test]
fn reduced_roundtrip_bug() {
let payload = Builder::new()
.start_compound("")
.start_list("aaa", Tag::Compound, 1)
.start_anon_compound()
.end_anon_compound()
.end_compound()
.build();
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Empty {}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct V {
aaa: Vec<Empty>,
}
let v: V = from_bytes(&payload).unwrap();
let bs = to_bytes(&v).unwrap();
let roundtrip: V = from_bytes(&bs).unwrap();
assert_eq!(roundtrip, v);
}
#[test]
fn empty_compound_root() {
#[derive(Serialize)]
struct Empty {}
#[derive(Serialize)]
struct Wrapper(Empty);
let payload = Builder::new().start_compound("").end_compound().build();
let bs1 = to_bytes(&Empty {}).unwrap();
let bs2 = to_bytes(&Wrapper(Empty {})).unwrap();
assert_eq!(payload, bs1);
assert_eq!(payload, bs2);
}
#[test]
fn no_root() {
assert!(to_bytes(&123_u8).is_err());
assert!(to_bytes(&123_u16).is_err());
assert!(to_bytes(&123_u32).is_err());
assert!(to_bytes(&123_u64).is_err());
assert!(to_bytes(&123_u128).is_err());
assert!(to_bytes(&123_i8).is_err());
assert!(to_bytes(&123_i16).is_err());
assert!(to_bytes(&123_i32).is_err());
assert!(to_bytes(&123_i64).is_err());
assert!(to_bytes(&123_i128).is_err());
assert!(to_bytes(&true).is_err());
assert!(to_bytes(&"hello").is_err());
assert!(to_bytes(&vec![1]).is_err());
assert!(to_bytes(&HashMap::<&str, ()>::new()).is_ok());
}
#[test]
fn list_of_bytebuf() {
#[derive(Serialize)]
struct V {
list: [ByteBuf; 1],
}
let v = V {
list: [ByteBuf::from([1, 2, 3])],
};
let actual = to_bytes(&v).unwrap();
let expected = Builder::new()
.start_compound("")
.start_list("list", Tag::List, 1)
.start_anon_list(Tag::Byte, 3)
.byte_payload(1)
.byte_payload(2)
.byte_payload(3)
.end_compound()
.build();
assert_eq!(expected, actual);
}
#[test]
fn list_with_none_errors() {
#[derive(Serialize)]
struct V {
list: [Option<u8>; 1],
}
let v = V { list: [None] };
assert!(to_bytes(&v).is_err());
}
#[test]
fn unit_errors() {
#[derive(Serialize)]
struct V {
unit: (),
}
#[derive(Serialize)]
struct VS {
unit: [(); 1],
}
let v = V { unit: () };
let vs = VS { unit: [()] };
assert!(to_bytes(&v).is_err());
assert!(to_bytes(&vs).is_err());
}
#[test]
fn unit_struct_errors() {
#[derive(Serialize)]
struct Unit;
#[derive(Serialize)]
struct V {
unit: Unit,
}
#[derive(Serialize)]
struct VS {
unit: [Unit; 1],
}
let v = V { unit: Unit };
let vs = VS { unit: [Unit] };
assert!(to_bytes(&v).is_err());
assert!(to_bytes(&vs).is_err());
}
#[test]
fn serialize_key_and_value() {
struct Dummy;
impl Serialize for Dummy {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut map = serializer.serialize_map(None)?;
map.serialize_key("test")?;
map.serialize_value("value")?;
map.end()
}
}
let bs = to_bytes(&Dummy).unwrap();
let actual = to_bytes(&nbt!({"test":"value"})).unwrap();
assert_eq!(actual, bs);
}
#[test]
fn issue_64() {
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename = "CamelCase")]
pub struct PlayerData {
#[serde(rename = "PersistentId")]
persistant_id: Option<i32>,
#[serde(rename = "playerGameType")]
game_type: i32,
abilities: PlayerAbilityData,
#[serde(rename = "Score")]
score: Option<i32>,
#[serde(rename = "Dimension")]
dimension: i32,
#[serde(rename = "OnGround")]
on_ground: bool,
#[serde(rename = "FallDistance")]
fall_distance: f32,
#[serde(rename = "Motion")]
motion: Vec<f64>, #[serde(rename = "Pos")]
position: Vec<f64>, #[serde(rename = "Rotation")]
rotation: Vec<f32>,
#[serde(rename = "SpawnX")]
spawn_x: i32,
#[serde(rename = "SpawnY")]
spawn_y: i32,
#[serde(rename = "SpawnZ")]
spawn_z: i32,
#[serde(rename = "SpawnForced")]
spawn_forced: Option<bool>,
#[serde(rename = "PortalCooldown")]
portal_cooldown: Option<i32>,
#[serde(rename = "Invulnerable")]
invulnerable: Option<bool>,
#[serde(rename = "AttackTime")]
attack_time: Option<i16>,
#[serde(rename = "HurtTime")]
hurt_time: i16,
#[serde(rename = "HurtByTimestamp")]
hurt_by: Option<i32>,
#[serde(rename = "DeathTime")]
death_time: i16,
#[serde(rename = "Sleeping")]
sleeping: bool,
#[serde(rename = "SleepTimer")]
sleep_timer: i16,
#[serde(rename = "Health")]
health: i16,
#[serde(rename = "HealF")]
heal: Option<f32>,
#[serde(rename = "foodLevel")]
food_level: i32,
#[serde(rename = "foodTickTimer")]
food_tick_timer: i32,
#[serde(rename = "foodSaturationLevel")]
food_saturation_level: f32,
#[serde(rename = "foodExhaustionLevel")]
food_exhaustion_level: f32,
#[serde(rename = "Fire")]
fire: i16,
#[serde(rename = "Air")]
air: i16,
#[serde(rename = "XpP")]
xp_p: f32,
#[serde(rename = "XpLevel")]
xp_level: i32,
#[serde(rename = "XpTotal")]
xp_total: i32,
#[serde(rename = "XpSeed")]
xp_seed: Option<i32>,
#[serde(rename = "Inventory")]
inventory: Vec<InventoryEntry>,
#[serde(rename = "EnderItems")]
ender_items: Vec<i8>,
#[serde(rename = "SelectedItemSlot")]
selected_item_slot: Option<i32>,
#[serde(rename = "SelectedItem")]
selected_item: Option<InventoryEntry>,
#[serde(rename = "UUIDLeast")]
uuid_least: Option<i64>,
#[serde(rename = "UUIDMost")]
uuid_most: Option<i64>,
#[serde(rename = "AbsorptionAmount")]
absorbtion_amount: Option<f32>,
#[serde(rename = "Attributes")]
attributes: Option<Vec<AttributeEntry>>,
#[serde(rename = "ActiveEffects")]
active_effects: Option<Vec<ActiveEffect>>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct PlayerAbilityData {
invulnerable: bool,
instabuild: bool,
flying: bool,
#[serde(rename = "flySpeed")]
fly_speed: f32,
#[serde(rename = "walkSpeed")]
walk_speed: f32,
#[serde(rename = "mayBuild")]
may_build: bool,
#[serde(rename = "mayfly")]
may_fly: bool,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct InventoryEntry {
id: String,
#[serde(rename = "Slot")]
slot: Option<i8>,
#[serde(rename = "Count")]
count: i8,
#[serde(rename = "Damage")]
damage: i16,
#[serde(rename = "tag")]
info: Option<InventoryEntryInfo>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct InventoryEntryInfo {
display: Option<InventoryEntryDisplay>,
#[serde(rename = "RepairCost")]
repair_cost: Option<i32>,
#[serde(rename = "ench")]
enchantments: Vec<Enchantment>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct InventoryEntryDisplay {
#[serde(rename = "Name")]
name: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Enchantment {
id: i16,
#[serde(rename = "lvl")]
level: i16,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct EnderItemsEntry {
id: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct AttributeEntry {
#[serde(rename = "Name")]
name: String,
#[serde(rename = "Base")]
base: f64,
#[serde(rename = "Modifiers")]
modifiers: Option<Vec<AttributeModifier>>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct AttributeModifier {
#[serde(rename = "Name")]
name: String,
#[serde(rename = "Amount")]
amount: f64,
#[serde(rename = "Operation")]
operation: i32,
#[serde(rename = "UUIDLeast")]
uuid_least: i64,
#[serde(rename = "UUIDMost")]
uuid_most: i64,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename = "CamelCase")]
pub struct ActiveEffect {
id: i8,
base: i32,
ambient: bool,
amplifier: bool,
show_particles: bool,
}
let mut dec = flate2::read::GzDecoder::new(resources::SIMPLE_PLAYER);
let mut payload = vec![];
dec.read_to_end(&mut payload).unwrap();
let v: PlayerData = from_bytes(&payload).unwrap();
let bs = to_bytes(&v).unwrap();
let v_trip: PlayerData = from_bytes(&bs).unwrap();
assert_eq!(v, v_trip);
}