diff options
| author | mat <github@matdoes.dev> | 2023-03-22 19:31:21 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2023-03-22 19:31:28 -0500 |
| commit | 03a672ee9bac20b20a498eec5328fb05db7aa3bb (patch) | |
| tree | 7bfcd9db93f3437663bfbb248ea75b95b099e728 | |
| parent | 228ee4a2f0f94975fc233946e0c4d258f87fbcf4 (diff) | |
| download | azalea-drasl-03a672ee9bac20b20a498eec5328fb05db7aa3bb.tar.xz | |
make nbt code more readable and add comparison benchmark
| -rw-r--r-- | Cargo.lock | 103 | ||||
| -rw-r--r-- | azalea-nbt/Cargo.toml | 8 | ||||
| -rwxr-xr-x | azalea-nbt/README.md | 2 | ||||
| -rwxr-xr-x | azalea-nbt/benches/comparison.rs | 125 | ||||
| -rwxr-xr-x | azalea-nbt/benches/my_benchmark.rs | 22 | ||||
| -rwxr-xr-x | azalea-nbt/src/decode.rs | 63 | ||||
| -rwxr-xr-x | azalea-nbt/src/encode.rs | 52 | ||||
| -rwxr-xr-x | azalea-nbt/src/tag.rs | 66 |
8 files changed, 341 insertions, 100 deletions
@@ -356,8 +356,12 @@ dependencies = [ "criterion", "enum-as-inner", "flate2", + "graphite_binary", + "hematite-nbt", "log", + "quartz_nbt", "serde", + "valence_nbt", ] [[package]] @@ -751,6 +755,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] name = "cfb8" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1253,6 +1263,31 @@ dependencies = [ ] [[package]] +name = "graphite_binary" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dc8b44c673c50a2b3e6ec6652b8c8d26532254a3a182cc43b76d1b6e4cd1572" +dependencies = [ + "anyhow", + "bytes", + "cesu8", + "graphite_binary_macros", + "thiserror", +] + +[[package]] +name = "graphite_binary_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30667bf8d368a37fa37f4165d90ee84362e360d83d85924898c41cfe3d097521" +dependencies = [ + "anyhow", + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "h2" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1294,6 +1329,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] +name = "hematite-nbt" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670d0784ee67cfb57393dc1837867d2951f9a59ca7db99a653499c854f745739" +dependencies = [ + "byteorder", + "cesu8", + "flate2", + "serde", +] + +[[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1822,6 +1869,30 @@ dependencies = [ ] [[package]] +name = "quartz_nbt" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348031720b71761481d77969dcb3c89ab06f04132ee1503aca1bd9313eef5e67" +dependencies = [ + "anyhow", + "byteorder", + "cesu8", + "flate2", + "quartz_nbt_macros", +] + +[[package]] +name = "quartz_nbt_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "289baa0c8a4d1f840d2de528a7f8c29e0e9af48b3018172b3edad4f716e8daed" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "quote" version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2539,6 +2610,17 @@ dependencies = [ ] [[package]] +name = "valence_nbt" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e84a1c10f1ee96e41060faa28ccf5937588a132e492502fbfd248381f19884b2" +dependencies = [ + "byteorder", + "cesu8", + "zerocopy", +] + +[[package]] name = "valuable" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2792,3 +2874,24 @@ checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] + +[[package]] +name = "zerocopy" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332f188cc1bcf1fe1064b8c58d150f497e697f49774aa846f2dc949d9a25f236" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6505e6815af7de1746a08f69c69606bb45695a17149517680f3b2149713b19a3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/azalea-nbt/Cargo.toml b/azalea-nbt/Cargo.toml index f68e13b0..59b52762 100644 --- a/azalea-nbt/Cargo.toml +++ b/azalea-nbt/Cargo.toml @@ -19,7 +19,11 @@ log = "0.4.17" serde = { version = "1.0.152", features = ["derive"], optional = true } [dev-dependencies] -criterion = {version = "^0.4.0", features = ["html_reports"]} +criterion = { version = "^0.4.0", features = ["html_reports"] } +graphite_binary = "0.1.0" +quartz_nbt = "0.2.6" +hematite-nbt = "0.5.2" +valence_nbt = "0.4.0" [features] default = [] @@ -27,8 +31,10 @@ serde = ["dep:serde", "ahash/serde"] [profile.release] lto = true +debug = true [profile.bench] +lto = true debug = true [[bench]] diff --git a/azalea-nbt/README.md b/azalea-nbt/README.md index 1feba8f5..63e0bfe7 100755 --- a/azalea-nbt/README.md +++ b/azalea-nbt/README.md @@ -2,6 +2,8 @@ A fast NBT serializer and deserializer. +Note: Running your code with `RUSTFLAGS="-C target-cpu=native"` will result in significant performance improvements. + # Examples ``` diff --git a/azalea-nbt/benches/comparison.rs b/azalea-nbt/benches/comparison.rs new file mode 100755 index 00000000..8ff2a54b --- /dev/null +++ b/azalea-nbt/benches/comparison.rs @@ -0,0 +1,125 @@ +use std::io::Cursor; + +use azalea_buf::McBufReadable; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +use nbt as hematite_nbt; +use quartz_nbt::io::Flavor; + +pub fn nbt_parse_bigtest(c: &mut Criterion) { + let original = include_bytes!("../tests/bigtest.nbt").to_vec(); + let mut original_stream = Cursor::new(original); + let original_tag = azalea_nbt::Tag::read_gzip(&mut original_stream).unwrap(); + let mut input = Vec::new(); + original_tag.write(&mut input).unwrap(); + let input = input.as_slice(); + + c.bench_function("azalea_parse_bigtest", |b| { + b.iter(|| { + let input = black_box(input); + let nbt = azalea_nbt::Tag::read(&mut Cursor::new(input)).unwrap(); + black_box(nbt); + }) + }); + + c.bench_function("graphite_parse_bigtest", |b| { + b.iter(|| { + let input = black_box(input); + let nbt = graphite_binary::nbt::decode::read(&mut &input[..]).unwrap(); + black_box(nbt); + }) + }); + + c.bench_function("valence_parse_bigtest", |b| { + b.iter(|| { + let input = black_box(input); + let nbt = valence_nbt::from_binary_slice(&mut &input[..]).unwrap(); + black_box(nbt); + }) + }); + + // c.bench_function("hematite_parse_bigtest", |b| { + // b.iter(|| { + // let input = black_box(input); + + // let cursor = Cursor::new(input); + // let blob: hematite_nbt::Blob = + // hematite_nbt::from_reader(cursor).unwrap(); black_box(blob); + // }) + // }); + + // c.bench_function("quartz_parse_bigtest", |b| { + // b.iter(|| { + // let input = black_box(input); + + // let mut cursor = Cursor::new(input); + // let nbt = quartz_nbt::io::read_nbt(&mut cursor, + // Flavor::Uncompressed).unwrap(); black_box(nbt); + // }) + // }); +} + +pub fn nbt_write_bigtest(c: &mut Criterion) { + let original = include_bytes!("../tests/bigtest.nbt").to_vec(); + let mut original_stream = Cursor::new(original); + let original_tag = azalea_nbt::Tag::read_gzip(&mut original_stream).unwrap(); + let mut input = Vec::new(); + original_tag.write(&mut input).unwrap(); + let input = input.as_slice(); + + let mut cursor = Cursor::new(input); + let nbt = azalea_nbt::Tag::read_from(&mut cursor).unwrap(); + c.bench_function("azalea_write_bigtest", |b| { + b.iter(|| { + let nbt = black_box(&nbt); + let mut written = Vec::new(); + nbt.write(&mut written).unwrap(); + black_box(written); + }) + }); + + let nbt = graphite_binary::nbt::decode::read(&mut &input[..]).unwrap(); + c.bench_function("graphite_write_bigtest", |b| { + b.iter(|| { + let nbt = black_box(&nbt); + let written = graphite_binary::nbt::encode::write(nbt); + black_box(written); + }) + }); + + let nbt = valence_nbt::from_binary_slice(&mut &input[..]).unwrap(); + c.bench_function("valence_write_bigtest", |b| { + b.iter(|| { + let nbt = black_box(&nbt); + let mut written = Vec::new(); + valence_nbt::to_binary_writer(&mut written, &nbt.0, &nbt.1).unwrap(); + black_box(written); + }) + }); + + // let cursor = Cursor::new(input); + // let nbt: hematite_nbt::Blob = hematite_nbt::from_reader(cursor).unwrap(); + // c.bench_function("hematite_write_bigtest", |b| { + // b.iter(|| { + // let nbt = black_box(&nbt); + // let mut written = Vec::new(); + // hematite_nbt::to_writer(&mut written, nbt, None).unwrap(); + // black_box(written); + // }) + // }); + + // let mut cursor = Cursor::new(input); + // let (nbt, _) = quartz_nbt::io::read_nbt(&mut cursor, + // Flavor::Uncompressed).unwrap(); c.bench_function(" + // quartz_write_bigtest", |b| { b.iter(|| { + // let nbt = black_box(&nbt); + // let mut written = Vec::new(); + // quartz_nbt::io::write_nbt(&mut written, None, nbt, + // Flavor::Uncompressed).unwrap(); black_box(written); + // }) + // }); +} + +// criterion_group!(benches, nbt_write_bigtest); +criterion_group!(benches, nbt_parse_bigtest, nbt_write_bigtest); +criterion_main!(benches); diff --git a/azalea-nbt/benches/my_benchmark.rs b/azalea-nbt/benches/my_benchmark.rs index 2e4efa97..5987e533 100755 --- a/azalea-nbt/benches/my_benchmark.rs +++ b/azalea-nbt/benches/my_benchmark.rs @@ -26,12 +26,12 @@ fn bench_serialize(filename: &str, c: &mut Criterion) { group.throughput(Throughput::Bytes(decoded_src.len() as u64)); - group.bench_function("Decode", |b| { - b.iter(|| { - black_box(Tag::read(&mut decoded_src_stream).unwrap()); - decoded_src_stream.set_position(0); - }) - }); + // group.bench_function("Decode", |b| { + // b.iter(|| { + // black_box(Tag::read(&mut decoded_src_stream).unwrap()); + // decoded_src_stream.set_position(0); + // }) + // }); group.bench_function("Encode", |b| { b.iter(|| { @@ -43,11 +43,11 @@ fn bench_serialize(filename: &str, c: &mut Criterion) { fn bench(c: &mut Criterion) { bench_serialize("tests/bigtest.nbt", c); - bench_serialize("tests/simple_player.dat", c); - bench_serialize("tests/complex_player.dat", c); - bench_serialize("tests/level.dat", c); - bench_serialize("tests/stringtest.nbt", c); - bench_serialize("tests/inttest.nbt", c); + // bench_serialize("tests/simple_player.dat", c); + // bench_serialize("tests/complex_player.dat", c); + // bench_serialize("tests/level.dat", c); + // bench_serialize("tests/stringtest.nbt", c); + // bench_serialize("tests/inttest.nbt", c); } criterion_group!(benches, bench); diff --git a/azalea-nbt/src/decode.rs b/azalea-nbt/src/decode.rs index da3c933c..635e2f6d 100755 --- a/azalea-nbt/src/decode.rs +++ b/azalea-nbt/src/decode.rs @@ -1,18 +1,11 @@ -use crate::tag::NbtByteArray; -use crate::tag::NbtCompound; -use crate::tag::NbtIntArray; -use crate::tag::NbtList; -use crate::tag::NbtLongArray; -use crate::tag::NbtString; +use crate::tag::*; use crate::Error; -use crate::Tag; use ahash::AHashMap; use azalea_buf::{BufReadError, McBufReadable}; use byteorder::{ReadBytesExt, BE}; use flate2::read::{GzDecoder, ZlibDecoder}; use log::warn; -use std::io::Cursor; -use std::io::{BufRead, Read}; +use std::io::{BufRead, Cursor, Read}; #[inline] fn read_bytes<'a>(buf: &'a mut Cursor<&[u8]>, length: usize) -> Result<&'a [u8], Error> { @@ -70,11 +63,11 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { let type_id = stream.read_u8()?; let length = stream.read_u32::<BE>()?; let list = match type_id { - 0 => NbtList::Empty, - 1 => NbtList::Byte(vec_u8_into_i8( + END_ID => NbtList::Empty, + BYTE_ID => NbtList::Byte(vec_u8_into_i8( read_bytes(stream, length as usize)?.to_vec(), )), - 2 => NbtList::Short({ + SHORT_ID => NbtList::Short({ if ((length * 2) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -82,7 +75,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| stream.read_i16::<BE>()) .collect::<Result<Vec<_>, _>>()? }), - 3 => NbtList::Int({ + INT_ID => NbtList::Int({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -90,7 +83,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| stream.read_i32::<BE>()) .collect::<Result<Vec<_>, _>>()? }), - 4 => NbtList::Long({ + LONG_ID => NbtList::Long({ if ((length * 8) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -98,7 +91,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| stream.read_i64::<BE>()) .collect::<Result<Vec<_>, _>>()? }), - 5 => NbtList::Float({ + FLOAT_ID => NbtList::Float({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -106,7 +99,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| stream.read_f32::<BE>()) .collect::<Result<Vec<_>, _>>()? }), - 6 => NbtList::Double({ + DOUBLE_ID => NbtList::Double({ if ((length * 8) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -114,7 +107,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| stream.read_f64::<BE>()) .collect::<Result<Vec<_>, _>>()? }), - 7 => NbtList::ByteArray({ + BYTE_ARRAY_ID => NbtList::ByteArray({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -122,7 +115,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| read_byte_array(stream)) .collect::<Result<Vec<_>, _>>()? }), - 8 => NbtList::String({ + STRING_ID => NbtList::String({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -130,7 +123,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| read_string(stream)) .collect::<Result<Vec<_>, _>>()? }), - 9 => NbtList::List({ + LIST_ID => NbtList::List({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -138,7 +131,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| read_list(stream)) .collect::<Result<Vec<_>, _>>()? }), - 10 => NbtList::Compound({ + COMPOUND_ID => NbtList::Compound({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -146,7 +139,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| read_compound(stream)) .collect::<Result<Vec<_>, _>>()? }), - 11 => NbtList::IntArray({ + INT_ARRAY_ID => NbtList::IntArray({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -154,7 +147,7 @@ fn read_list(stream: &mut Cursor<&[u8]>) -> Result<NbtList, Error> { .map(|_| read_int_array(stream)) .collect::<Result<Vec<_>, _>>()? }), - 12 => NbtList::LongArray({ + LONG_ARRAY_ID => NbtList::LongArray({ if ((length * 4) as usize) > (stream.get_ref().len() - stream.position() as usize) { return Err(Error::UnexpectedEof); } @@ -217,28 +210,28 @@ impl Tag { Ok(match id { // Signifies the end of a TAG_Compound. It is only ever used inside // a TAG_Compound, and is not named despite being in a TAG_Compound - 0 => Tag::End, + END_ID => Tag::End, // A single signed byte - 1 => Tag::Byte(stream.read_i8()?), + BYTE_ID => Tag::Byte(stream.read_i8()?), // A single signed, big endian 16 bit integer - 2 => Tag::Short(stream.read_i16::<BE>()?), + SHORT_ID => Tag::Short(stream.read_i16::<BE>()?), // A single signed, big endian 32 bit integer - 3 => Tag::Int(stream.read_i32::<BE>()?), + INT_ID => Tag::Int(stream.read_i32::<BE>()?), // A single signed, big endian 64 bit integer - 4 => Tag::Long(stream.read_i64::<BE>()?), + LONG_ID => Tag::Long(stream.read_i64::<BE>()?), // A single, big endian IEEE-754 single-precision floating point // number (NaN possible) - 5 => Tag::Float(stream.read_f32::<BE>()?), + FLOAT_ID => Tag::Float(stream.read_f32::<BE>()?), // A single, big endian IEEE-754 double-precision floating point // number (NaN possible) - 6 => Tag::Double(stream.read_f64::<BE>()?), + DOUBLE_ID => Tag::Double(stream.read_f64::<BE>()?), // A length-prefixed array of signed bytes. The prefix is a signed // integer (thus 4 bytes) - 7 => Tag::ByteArray(read_byte_array(stream)?), + BYTE_ARRAY_ID => Tag::ByteArray(read_byte_array(stream)?), // A length-prefixed modified UTF-8 string. The prefix is an // unsigned short (thus 2 bytes) signifying the length of the // string in bytes - 8 => Tag::String(read_string(stream)?), + STRING_ID => Tag::String(read_string(stream)?), // A list of nameless tags, all of the same type. The list is // prefixed with the Type ID of the items it contains (thus 1 // byte), and the length of the list as a signed integer (a further @@ -247,16 +240,16 @@ impl Tag { // notchian implementation uses TAG_End in that situation, but // another reference implementation by Mojang uses 1 instead; // parsers should accept any type if the length is <= 0). - 9 => Tag::List(read_list(stream)?), + LIST_ID => Tag::List(read_list(stream)?), // Effectively a list of a named tags. Order is not guaranteed. - 10 => Tag::Compound(read_compound(stream)?), + COMPOUND_ID => Tag::Compound(read_compound(stream)?), // A length-prefixed array of signed integers. The prefix is a // signed integer (thus 4 bytes) and indicates the number of 4 byte // integers. - 11 => Tag::IntArray(read_int_array(stream)?), + INT_ARRAY_ID => Tag::IntArray(read_int_array(stream)?), // A length-prefixed array of signed longs. The prefix is a signed // integer (thus 4 bytes) and indicates the number of 8 byte longs. - 12 => Tag::LongArray(read_long_array(stream)?), + LONG_ARRAY_ID => Tag::LongArray(read_long_array(stream)?), _ => return Err(Error::InvalidTagType(id)), }) } diff --git a/azalea-nbt/src/encode.rs b/azalea-nbt/src/encode.rs index 8dfd8fa4..ba2b77a5 100755 --- a/azalea-nbt/src/encode.rs +++ b/azalea-nbt/src/encode.rs @@ -1,7 +1,5 @@ -use crate::tag::NbtCompound; -use crate::tag::NbtList; +use crate::tag::*; use crate::Error; -use crate::Tag; use azalea_buf::McBufWritable; use byteorder::{WriteBytesExt, BE}; use flate2::write::{GzEncoder, ZlibEncoder}; @@ -21,62 +19,62 @@ fn write_compound(writer: &mut dyn Write, value: &NbtCompound, end_tag: bool) -> match tag { Tag::End => {} Tag::Byte(value) => { - writer.write_u8(1)?; + writer.write_u8(BYTE_ID)?; write_string(writer, key)?; writer.write_i8(*value)?; } Tag::Short(value) => { - writer.write_u8(2)?; + writer.write_u8(SHORT_ID)?; write_string(writer, key)?; writer.write_i16::<BE>(*value)?; } Tag::Int(value) => { - writer.write_u8(3)?; + writer.write_u8(INT_ID)?; write_string(writer, key)?; writer.write_i32::<BE>(*value)?; } Tag::Long(value) => { - writer.write_u8(4)?; + writer.write_u8(LONG_ID)?; write_string(writer, key)?; writer.write_i64::<BE>(*value)?; } Tag::Float(value) => { - writer.write_u8(5)?; + writer.write_u8(FLOAT_ID)?; write_string(writer, key)?; writer.write_f32::<BE>(*value)?; } Tag::Double(value) => { - writer.write_u8(6)?; + writer.write_u8(DOUBLE_ID)?; write_string(writer, key)?; writer.write_f64::<BE>(*value)?; } Tag::ByteArray(value) => { - writer.write_u8(7)?; + writer.write_u8(BYTE_ARRAY_ID)?; write_string(writer, key)?; write_byte_array(writer, value)?; } Tag::String(value) => { - writer.write_u8(8)?; + writer.write_u8(STRING_ID)?; write_string(writer, key)?; write_string(writer, value)?; } Tag::List(value) => { - writer.write_u8(9)?; + writer.write_u8(LIST_ID)?; write_string(writer, key)?; write_list(writer, value)?; } Tag::Compound(value) => { - writer.write_u8(10)?; + writer.write_u8(COMPOUND_ID)?; write_string(writer, key)?; write_compound(writer, value, true)?; } Tag::IntArray(value) => { - writer.write_u8(11)?; + writer.write_u8(INT_ARRAY_ID)?; write_string(writer, key)?; write_int_array(writer, value)?; } Tag::LongArray(value) => { - writer.write_u8(12)?; + writer.write_u8(LONG_ARRAY_ID)?; write_string(writer, key)?; write_long_array(writer, value)?; } @@ -93,84 +91,84 @@ fn write_list(writer: &mut dyn Write, value: &NbtList) -> Result<(), Error> { match value { NbtList::Empty => writer.write_all(&[0; 5])?, NbtList::Byte(l) => { - writer.write_u8(1)?; + writer.write_u8(BYTE_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { writer.write_i8(*v)?; } } NbtList::Short(l) => { - writer.write_u8(2)?; + writer.write_u8(SHORT_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { writer.write_i16::<BE>(*v)?; } } NbtList::Int(l) => { - writer.write_u8(3)?; + writer.write_u8(INT_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { writer.write_i32::<BE>(*v)?; } } NbtList::Long(l) => { - writer.write_u8(4)?; + writer.write_u8(LONG_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { writer.write_i64::<BE>(*v)?; } } NbtList::Float(l) => { - writer.write_u8(5)?; + writer.write_u8(FLOAT_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { writer.write_f32::<BE>(*v)?; } } NbtList::Double(l) => { - writer.write_u8(6)?; + writer.write_u8(DOUBLE_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { writer.write_f64::<BE>(*v)?; } } NbtList::ByteArray(l) => { - writer.write_u8(7)?; + writer.write_u8(BYTE_ARRAY_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { write_byte_array(writer, v)?; } } NbtList::String(l) => { - writer.write_u8(8)?; + writer.write_u8(STRING_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { write_string(writer, v)?; } } NbtList::List(l) => { - writer.write_u8(9)?; + writer.write_u8(LIST_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { write_list(writer, v)?; } } NbtList::Compound(l) => { - writer.write_u8(10)?; + writer.write_u8(COMPOUND_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { write_compound(writer, v, true)?; } } NbtList::IntArray(l) => { - writer.write_u8(11)?; + writer.write_u8(INT_ARRAY_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { write_int_array(writer, v)?; } } NbtList::LongArray(l) => { - writer.write_u8(12)?; + writer.write_u8(LONG_ARRAY_ID)?; writer.write_i32::<BE>(l.len() as i32)?; for v in l { write_long_array(writer, v)?; diff --git a/azalea-nbt/src/tag.rs b/azalea-nbt/src/tag.rs index 4a702339..e1aecb91 100755 --- a/azalea-nbt/src/tag.rs +++ b/azalea-nbt/src/tag.rs @@ -17,25 +17,39 @@ pub type NbtCompound = AHashMap<CompactString, Tag>; pub type NbtIntArray = Vec<i32>; pub type NbtLongArray = Vec<i64>; +pub const END_ID: u8 = 0; +pub const BYTE_ID: u8 = 1; +pub const SHORT_ID: u8 = 2; +pub const INT_ID: u8 = 3; +pub const LONG_ID: u8 = 4; +pub const FLOAT_ID: u8 = 5; +pub const DOUBLE_ID: u8 = 6; +pub const BYTE_ARRAY_ID: u8 = 7; +pub const STRING_ID: u8 = 8; +pub const LIST_ID: u8 = 9; +pub const COMPOUND_ID: u8 = 10; +pub const INT_ARRAY_ID: u8 = 11; +pub const LONG_ARRAY_ID: u8 = 12; + /// An NBT value. #[derive(Clone, Debug, PartialEq, Default, EnumAsInner)] #[repr(u8)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))] pub enum Tag { #[default] - End = 0, - Byte(NbtByte) = 1, - Short(NbtShort) = 2, - Int(NbtInt) = 3, - Long(NbtLong) = 4, - Float(NbtFloat) = 5, - Double(NbtDouble) = 6, - ByteArray(NbtByteArray) = 7, - String(NbtString) = 8, - List(NbtList) = 9, - Compound(NbtCompound) = 10, - IntArray(NbtIntArray) = 11, - LongArray(NbtLongArray) = 12, + End = END_ID, + Byte(NbtByte) = BYTE_ID, + Short(NbtShort) = SHORT_ID, + Int(NbtInt) = INT_ID, + Long(NbtLong) = LONG_ID, + Float(NbtFloat) = FLOAT_ID, + Double(NbtDouble) = DOUBLE_ID, + ByteArray(NbtByteArray) = BYTE_ARRAY_ID, + String(NbtString) = STRING_ID, + List(NbtList) = LIST_ID, + Compound(NbtCompound) = COMPOUND_ID, + IntArray(NbtIntArray) = INT_ARRAY_ID, + LongArray(NbtLongArray) = LONG_ARRAY_ID, } /// An NBT value. @@ -43,19 +57,19 @@ pub enum Tag { #[repr(u8)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(untagged))] pub enum NbtList { - Empty, - Byte(Vec<NbtByte>) = 1, - Short(Vec<NbtShort>) = 2, - Int(Vec<NbtInt>) = 3, - Long(Vec<NbtLong>) = 4, - Float(Vec<NbtFloat>) = 5, - Double(Vec<NbtDouble>) = 6, - ByteArray(Vec<NbtByteArray>) = 7, - String(Vec<NbtString>) = 8, - List(Vec<NbtList>) = 9, - Compound(Vec<NbtCompound>) = 10, - IntArray(Vec<NbtIntArray>) = 11, - LongArray(Vec<NbtLongArray>) = 12, + Empty = END_ID, + Byte(Vec<NbtByte>) = BYTE_ID, + Short(Vec<NbtShort>) = SHORT_ID, + Int(Vec<NbtInt>) = INT_ID, + Long(Vec<NbtLong>) = LONG_ID, + Float(Vec<NbtFloat>) = FLOAT_ID, + Double(Vec<NbtDouble>) = DOUBLE_ID, + ByteArray(Vec<NbtByteArray>) = BYTE_ARRAY_ID, + String(Vec<NbtString>) = STRING_ID, + List(Vec<NbtList>) = LIST_ID, + Compound(Vec<NbtCompound>) = COMPOUND_ID, + IntArray(Vec<NbtIntArray>) = INT_ARRAY_ID, + LongArray(Vec<NbtLongArray>) = LONG_ARRAY_ID, } impl Tag { |
