1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 23:44:38 +00:00

slightly optimize azalea_nbt::Tag::id

This commit is contained in:
mat 2023-03-11 16:38:13 -06:00
commit 40a0c8acfb
3 changed files with 28 additions and 54 deletions

View file

@ -7,11 +7,9 @@ A fast NBT serializer and deserializer.
``` ```
use ahash::AHashMap; use ahash::AHashMap;
use azalea_nbt::Tag; 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 buf = include_bytes!("../tests/hello_world.nbt");
let mut buf = vec![];
file.read_to_end(&mut buf).unwrap();
let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap(); let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap();
assert_eq!( assert_eq!(
tag, tag,

View file

@ -5,43 +5,34 @@ use serde::{Deserialize, Serialize};
/// An NBT value. /// An NBT value.
#[derive(Clone, Debug, PartialEq, Default)] #[derive(Clone, Debug, PartialEq, Default)]
#[repr(u8)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))]
pub enum Tag { pub enum Tag {
#[default] #[default]
End, // 0 End = 0,
Byte(i8), // 1 Byte(i8) = 1,
Short(i16), // 2 Short(i16) = 2,
Int(i32), // 3 Int(i32) = 3,
Long(i64), // 4 Long(i64) = 4,
Float(f32), // 5 Float(f32) = 5,
Double(f64), // 6 Double(f64) = 6,
ByteArray(Vec<u8>), // 7 ByteArray(Vec<u8>) = 7,
String(String), // 8 String(String) = 8,
List(Vec<Tag>), // 9 List(Vec<Tag>) = 9,
Compound(AHashMap<String, Tag>), // 10 Compound(AHashMap<String, Tag>) = 10,
IntArray(Vec<i32>), // 11 IntArray(Vec<i32>) = 11,
LongArray(Vec<i64>), // 12 LongArray(Vec<i64>) = 12,
} }
impl Tag { impl Tag {
/// Get the numerical ID of the tag type. /// Get the numerical ID of the tag type.
#[inline] #[inline]
pub fn id(&self) -> u8 { pub fn id(&self) -> u8 {
match self { // SAFETY: Because `Self` is marked `repr(u8)`, its layout is a `repr(C)`
Tag::End => 0, // `union` between `repr(C)` structs, each of which has the `u8`
Tag::Byte(_) => 1, // discriminant as its first field, so we can read the discriminant
Tag::Short(_) => 2, // without offsetting the pointer.
Tag::Int(_) => 3, unsafe { *<*const _>::from(self).cast::<u8>() }
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,
}
} }
/// If the type is a byte, return the [`i8`]. /// If the type is a byte, return the [`i8`].

View file

@ -1,16 +1,11 @@
use ahash::AHashMap; use ahash::AHashMap;
use azalea_nbt::Tag; use azalea_nbt::Tag;
use std::{ use std::io::Cursor;
fs::File,
io::{Cursor, Read},
};
#[test] #[test]
fn test_decode_hello_world() { fn test_decode_hello_world() {
// read hello_world.nbt // read hello_world.nbt
let mut file = File::open("tests/hello_world.nbt").unwrap(); let buf = include_bytes!("hello_world.nbt").to_vec();
let mut buf = vec![];
file.read_to_end(&mut buf).unwrap();
let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap(); let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap();
assert_eq!( assert_eq!(
tag, tag,
@ -26,9 +21,7 @@ fn test_decode_hello_world() {
#[test] #[test]
fn test_roundtrip_hello_world() { fn test_roundtrip_hello_world() {
let mut file = File::open("tests/hello_world.nbt").unwrap(); let original = include_bytes!("hello_world.nbt").to_vec();
let mut original = Vec::new();
file.read_to_end(&mut original).unwrap();
let mut original_stream = Cursor::new(&original[..]); let mut original_stream = Cursor::new(&original[..]);
let tag = Tag::read(&mut original_stream).unwrap(); let tag = Tag::read(&mut original_stream).unwrap();
@ -43,9 +36,7 @@ fn test_roundtrip_hello_world() {
#[test] #[test]
fn test_bigtest() { fn test_bigtest() {
// read bigtest.nbt // read bigtest.nbt
let mut file = File::open("tests/bigtest.nbt").unwrap(); let original = include_bytes!("bigtest.nbt").to_vec();
let mut original = Vec::new();
file.read_to_end(&mut original).unwrap();
let mut original_stream = Cursor::new(original); let mut original_stream = Cursor::new(original);
let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); let original_tag = Tag::read_gzip(&mut original_stream).unwrap();
@ -81,9 +72,7 @@ fn test_stringtest() {
Tag::String("😁".to_string()), Tag::String("😁".to_string()),
]) ])
)])); )]));
let mut file = std::fs::File::open("tests/stringtest.nbt").unwrap(); let original = include_bytes!("stringtest.nbt").to_vec();
let mut original = Vec::new();
file.read_to_end(&mut original).unwrap();
let mut original_stream = Cursor::new(original); let mut original_stream = Cursor::new(original);
let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); let original_tag = Tag::read_gzip(&mut original_stream).unwrap();
@ -93,9 +82,7 @@ fn test_stringtest() {
#[test] #[test]
fn test_complex_player() { fn test_complex_player() {
let mut file = File::open("tests/complex_player.dat").unwrap(); let original = include_bytes!("complex_player.dat").to_vec();
let mut original = Vec::new();
file.read_to_end(&mut original).unwrap();
let mut original_stream = Cursor::new(original); let mut original_stream = Cursor::new(original);
let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); let original_tag = Tag::read_gzip(&mut original_stream).unwrap();
@ -110,9 +97,7 @@ fn test_complex_player() {
#[test] #[test]
fn test_simple_player() { fn test_simple_player() {
let mut file = File::open("tests/simple_player.dat").unwrap(); let original = include_bytes!("simple_player.dat").to_vec();
let mut original = Vec::new();
file.read_to_end(&mut original).unwrap();
let mut original_stream = Cursor::new(original); let mut original_stream = Cursor::new(original);
let original_tag = Tag::read_gzip(&mut original_stream).unwrap(); let original_tag = Tag::read_gzip(&mut original_stream).unwrap();