fastnbt 2.3.2

Serde deserializer for Minecraft's NBT format
Documentation
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("")
        // All bits are 1
        .int_array("max", &[u32::MAX as i32; 4])
        // Only first bit is 1
        .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) // we're missing the element tag and size here.
        // First list
        .start_anon_list(Tag::Byte, 1)
        .byte_payload(1)
        // second
        .start_anon_list(Tag::Byte, 1)
        .byte_payload(2)
        // third
        .start_anon_list(Tag::Byte, 1)
        .byte_payload(3)
        // end outer compound
        .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)
        // First list
        .start_anon_list(Tag::Compound, 1)
        .start_anon_compound()
        .int("val", 1)
        .end_anon_compound()
        // second
        .start_anon_list(Tag::Compound, 1)
        .start_anon_compound()
        .int("val", 2)
        .end_anon_compound()
        // third
        .start_anon_list(Tag::Compound, 1)
        .start_anon_compound()
        .int("val", 3)
        .end_anon_compound()
        // end outer 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::Unit;
    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();

    // hashmap order not predictable.
    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() {
    // Empty list ends up as a list of End tags, since there's no way to tell
    // what the type of the elements are, since serializing an element doesn't
    // happen for an 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() {
    // TODO: also do for other tag types.
    assert!(matches!(to_bytes(&123), Err(_)));
}

#[test]
fn list_of_empty_lists() {
    // Similar to the PostProcessing part of a chunk (at least in older
    // versions)
    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() {
    // Deserialize, serialize, and deserialize again. The two Values should be
    // the same.
    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() {
    // Even serde_bytes gets serialized to just a list of bytes. Only the
    // dedicated fastnbt array types get serialized to NBT arrays.
    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() {
    // This unicode character is an example character that is different when
    // encoded with cesu8 and utf8.
    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") // should deserialize as B?
        .end_compound()
        .build();

    let actual = to_bytes(&v).unwrap();

    assert_eq!(actual, expected);
}

#[test]
fn reduced_roundtrip_bug() {
    // When you have an empty compound, MapSerialize doesn't call
    // serialize_entry at all, which makes sense. This would be fine except we
    // delay writing the tag and name of the compound until the first key-value
    // entry is being written. This delay is because NBT arrays are modelled in
    // serde as maps with a special key-value entry, and we don't want to
    // serialize the compound tag if it turns out to be a NBT array instead.
    //
    // This however means that if an empty compound is serialized, that
    // serialize_entry doesn't get called and we end up not writing the compound
    // tag or name as a result. The fix is to detect in the end() call that we
    // haven't written the header, and write it.

    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>,
    }

    // Chunk looks fine as judged by println
    let v: V = from_bytes(&payload).unwrap();

    // This potentially broken?
    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>, // [f64; 3]
        #[serde(rename = "Pos")]
        position: Vec<f64>, // [f64; 3]
        #[serde(rename = "Rotation")]
        rotation: Vec<f32>, // [f32; 2]

        #[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);
}