diff --git a/azalea-nbt/README.md b/azalea-nbt/README.md index 5204c2d4..27de2fa6 100755 --- a/azalea-nbt/README.md +++ b/azalea-nbt/README.md @@ -7,11 +7,9 @@ A fast NBT serializer and deserializer. ``` use ahash::AHashMap; use azalea_nbt::Tag; -use std::{io::{Cursor, Read}, fs::File}; +use std::io::Cursor; -let mut file = File::open("tests/hello_world.nbt").unwrap(); -let mut buf = vec![]; -file.read_to_end(&mut buf).unwrap(); +let buf = include_bytes!("../tests/hello_world.nbt"); let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap(); assert_eq!( tag, diff --git a/azalea-nbt/src/tag.rs b/azalea-nbt/src/tag.rs index 23bed1d4..87a7374d 100755 --- a/azalea-nbt/src/tag.rs +++ b/azalea-nbt/src/tag.rs @@ -5,43 +5,34 @@ use serde::{Deserialize, Serialize}; /// An NBT value. #[derive(Clone, Debug, PartialEq, Default)] +#[repr(u8)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))] pub enum Tag { #[default] - End, // 0 - Byte(i8), // 1 - Short(i16), // 2 - Int(i32), // 3 - Long(i64), // 4 - Float(f32), // 5 - Double(f64), // 6 - ByteArray(Vec), // 7 - String(String), // 8 - List(Vec), // 9 - Compound(AHashMap), // 10 - IntArray(Vec), // 11 - LongArray(Vec), // 12 + End = 0, + Byte(i8) = 1, + Short(i16) = 2, + Int(i32) = 3, + Long(i64) = 4, + Float(f32) = 5, + Double(f64) = 6, + ByteArray(Vec) = 7, + String(String) = 8, + List(Vec) = 9, + Compound(AHashMap) = 10, + IntArray(Vec) = 11, + LongArray(Vec) = 12, } impl Tag { /// Get the numerical ID of the tag type. #[inline] pub fn id(&self) -> u8 { - match self { - Tag::End => 0, - Tag::Byte(_) => 1, - Tag::Short(_) => 2, - Tag::Int(_) => 3, - Tag::Long(_) => 4, - Tag::Float(_) => 5, - Tag::Double(_) => 6, - Tag::ByteArray(_) => 7, - Tag::String(_) => 8, - Tag::List(_) => 9, - Tag::Compound(_) => 10, - Tag::IntArray(_) => 11, - Tag::LongArray(_) => 12, - } + // SAFETY: Because `Self` is marked `repr(u8)`, its layout is a `repr(C)` + // `union` between `repr(C)` structs, each of which has the `u8` + // discriminant as its first field, so we can read the discriminant + // without offsetting the pointer. + unsafe { *<*const _>::from(self).cast::() } } /// If the type is a byte, return the [`i8`]. diff --git a/azalea-nbt/tests/tests.rs b/azalea-nbt/tests/tests.rs index 43c31590..c44eb818 100755 --- a/azalea-nbt/tests/tests.rs +++ b/azalea-nbt/tests/tests.rs @@ -1,16 +1,11 @@ use ahash::AHashMap; use azalea_nbt::Tag; -use std::{ - fs::File, - io::{Cursor, Read}, -}; +use std::io::Cursor; #[test] fn test_decode_hello_world() { // read hello_world.nbt - let mut file = File::open("tests/hello_world.nbt").unwrap(); - let mut buf = vec![]; - file.read_to_end(&mut buf).unwrap(); + let buf = include_bytes!("hello_world.nbt").to_vec(); let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap(); assert_eq!( tag, @@ -26,9 +21,7 @@ fn test_decode_hello_world() { #[test] fn test_roundtrip_hello_world() { - let mut file = File::open("tests/hello_world.nbt").unwrap(); - let mut original = Vec::new(); - file.read_to_end(&mut original).unwrap(); + let original = include_bytes!("hello_world.nbt").to_vec(); let mut original_stream = Cursor::new(&original[..]); let tag = Tag::read(&mut original_stream).unwrap(); @@ -43,9 +36,7 @@ fn test_roundtrip_hello_world() { #[test] fn test_bigtest() { // read bigtest.nbt - let mut file = File::open("tests/bigtest.nbt").unwrap(); - let mut original = Vec::new(); - file.read_to_end(&mut original).unwrap(); + let original = include_bytes!("bigtest.nbt").to_vec(); let mut original_stream = Cursor::new(original); let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); @@ -81,9 +72,7 @@ fn test_stringtest() { Tag::String("😁".to_string()), ]) )])); - let mut file = std::fs::File::open("tests/stringtest.nbt").unwrap(); - let mut original = Vec::new(); - file.read_to_end(&mut original).unwrap(); + let original = include_bytes!("stringtest.nbt").to_vec(); let mut original_stream = Cursor::new(original); let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); @@ -93,9 +82,7 @@ fn test_stringtest() { #[test] fn test_complex_player() { - let mut file = File::open("tests/complex_player.dat").unwrap(); - let mut original = Vec::new(); - file.read_to_end(&mut original).unwrap(); + let original = include_bytes!("complex_player.dat").to_vec(); let mut original_stream = Cursor::new(original); let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); @@ -110,9 +97,7 @@ fn test_complex_player() { #[test] fn test_simple_player() { - let mut file = File::open("tests/simple_player.dat").unwrap(); - let mut original = Vec::new(); - file.read_to_end(&mut original).unwrap(); + let original = include_bytes!("simple_player.dat").to_vec(); let mut original_stream = Cursor::new(original); let original_tag = Tag::read_gzip(&mut original_stream).unwrap();