use compact_str in nbt

This commit is contained in:
mat 2023-03-22 13:52:38 +00:00
parent b276978195
commit 6738be8090
8 changed files with 76 additions and 36 deletions

36
Cargo.lock generated
View file

@ -352,6 +352,7 @@ dependencies = [
"ahash 0.8.3",
"azalea-buf",
"byteorder",
"compact_str",
"criterion",
"flate2",
"log",
@ -733,6 +734,15 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "castaway"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc"
dependencies = [
"rustversion",
]
[[package]]
name = "cc"
version = "1.0.79"
@ -822,6 +832,20 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "compact_str"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bff0805f79ecb1b35163f3957a6934ea8d04fcd36ef98b52e7316f63e72e73d1"
dependencies = [
"castaway",
"cfg-if",
"itoa",
"ryu",
"serde",
"static_assertions",
]
[[package]]
name = "concurrent-queue"
version = "2.1.0"
@ -1999,6 +2023,12 @@ dependencies = [
"base64",
]
[[package]]
name = "rustversion"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06"
[[package]]
name = "ryu"
version = "1.0.13"
@ -2154,6 +2184,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.109"

View file

@ -12,6 +12,7 @@ repository = "https://github.com/mat-1/azalea/tree/main/azalea-nbt"
ahash = { version = "^0.8.3" }
azalea-buf = { path = "../azalea-buf", version = "^0.6.0" }
byteorder = "^1.4.3"
compact_str = { version = "0.7.0", features = ["serde"] }
flate2 = "^1.0.25"
log = "0.4.17"
serde = { version = "1.0.152", features = ["derive"], optional = true }

View file

@ -14,10 +14,10 @@ let tag = Tag::read(&mut Cursor::new(&buf[..])).unwrap();
assert_eq!(
tag,
Tag::Compound(AHashMap::from_iter(vec![(
"hello world".to_string(),
"hello world".into(),
Tag::Compound(AHashMap::from_iter(vec![(
"name".to_string(),
Tag::String("Bananrama".to_string()),
"name".into(),
Tag::String("Bananrama".into()),
)]))
)]))
);

View file

@ -3,6 +3,7 @@ use crate::Tag;
use ahash::AHashMap;
use azalea_buf::{BufReadError, McBufReadable};
use byteorder::{ReadBytesExt, BE};
use compact_str::CompactString;
use flate2::read::{GzDecoder, ZlibDecoder};
use log::warn;
use std::io::Cursor;
@ -20,17 +21,17 @@ fn read_bytes<'a>(buf: &'a mut Cursor<&[u8]>, length: usize) -> Result<&'a [u8],
}
#[inline]
fn read_string(stream: &mut Cursor<&[u8]>) -> Result<String, Error> {
fn read_string(stream: &mut Cursor<&[u8]>) -> Result<CompactString, Error> {
let length = stream.read_u16::<BE>()? as usize;
let buf = read_bytes(stream, length)?;
Ok(if let Ok(string) = std::str::from_utf8(buf) {
string.to_string()
string.into()
} else {
let lossy_string = String::from_utf8_lossy(buf).into_owned();
warn!("Error decoding utf8 (bytes: {buf:?}, lossy: \"{lossy_string})\"");
lossy_string
lossy_string.into()
})
}

View file

@ -3,6 +3,7 @@ use crate::Tag;
use ahash::AHashMap;
use azalea_buf::McBufWritable;
use byteorder::{WriteBytesExt, BE};
use compact_str::CompactString;
use flate2::write::{GzEncoder, ZlibEncoder};
use std::io::Write;
@ -17,7 +18,7 @@ fn write_string(writer: &mut dyn Write, string: &str) -> Result<(), Error> {
#[inline]
fn write_compound(
writer: &mut dyn Write,
value: &AHashMap<String, Tag>,
value: &AHashMap<CompactString, Tag>,
end_tag: bool,
) -> Result<(), Error> {
for (key, tag) in value {

View file

@ -20,10 +20,10 @@ mod tests {
fn mcbuf_nbt() {
let mut buf = Vec::new();
let tag = Tag::Compound(AHashMap::from_iter(vec![(
"hello world".to_string(),
"hello world".into(),
Tag::Compound(AHashMap::from_iter(vec![(
"name".to_string(),
Tag::String("Bananrama".to_string()),
"name".into(),
Tag::String("Bananrama".into()),
)])),
)]));
tag.write_into(&mut buf).unwrap();
@ -34,10 +34,10 @@ mod tests {
assert_eq!(
result,
Tag::Compound(AHashMap::from_iter(vec![(
"hello world".to_string(),
"hello world".into(),
Tag::Compound(AHashMap::from_iter(vec![(
"name".to_string(),
Tag::String("Bananrama".to_string()),
"name".into(),
Tag::String("Bananrama".into()),
)])),
)]))
);

View file

@ -1,5 +1,6 @@
use ahash::AHashMap;
use compact_str::CompactString;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
@ -17,9 +18,9 @@ pub enum Tag {
Float(f32) = 5,
Double(f64) = 6,
ByteArray(Vec<u8>) = 7,
String(String) = 8,
String(CompactString) = 8,
List(Vec<Tag>) = 9,
Compound(AHashMap<String, Tag>) = 10,
Compound(AHashMap<CompactString, Tag>) = 10,
IntArray(Vec<i32>) = 11,
LongArray(Vec<i64>) = 12,
}
@ -107,7 +108,7 @@ impl Tag {
/// If the type is a compound, return the `AHashMap<String, Tag>`.
#[inline]
pub fn as_compound(&self) -> Option<&AHashMap<String, Tag>> {
pub fn as_compound(&self) -> Option<&AHashMap<CompactString, Tag>> {
if let Tag::Compound(v) = self {
Some(v)
} else {

View file

@ -10,10 +10,10 @@ fn test_decode_hello_world() {
assert_eq!(
tag,
Tag::Compound(AHashMap::from_iter(vec![(
"hello world".to_string(),
"hello world".into(),
Tag::Compound(AHashMap::from_iter(vec![(
"name".to_string(),
Tag::String("Bananrama".to_string()),
"name".into(),
Tag::String("Bananrama".into()),
)]))
)]))
);
@ -52,24 +52,24 @@ fn test_bigtest() {
#[test]
fn test_stringtest() {
let correct_tag = Tag::Compound(AHashMap::from_iter(vec![(
"😃".to_string(),
"😃".into(),
Tag::List(vec![
Tag::String("asdfkghasfjgihsdfogjsndfg".to_string()),
Tag::String("jnabsfdgihsabguiqwrntgretqwejirhbiqw".to_string()),
Tag::String("asd".to_string()),
Tag::String("wqierjgt7wqy8u4rtbwreithwretiwerutbwenryq8uwervqwer9iuqwbrgyuqrbtwierotugqewrtqwropethert".to_string()),
Tag::String("asdf".to_string()),
Tag::String("alsdkjiqwoe".to_string()),
Tag::String("lmqi9hyqd".to_string()),
Tag::String("qwertyuiop".to_string()),
Tag::String("asdfghjkl".to_string()),
Tag::String("zxcvbnm".to_string()),
Tag::String(" ".to_string()),
Tag::String("words words words words words words".to_string()),
Tag::String("aaaaaaaaaaaaaaaaaaaa".to_string()),
Tag::String("".to_string()),
Tag::String("a\nb\n\n\nc\r\rd".to_string()),
Tag::String("😁".to_string()),
Tag::String("asdfkghasfjgihsdfogjsndfg".into()),
Tag::String("jnabsfdgihsabguiqwrntgretqwejirhbiqw".into()),
Tag::String("asd".into()),
Tag::String("wqierjgt7wqy8u4rtbwreithwretiwerutbwenryq8uwervqwer9iuqwbrgyuqrbtwierotugqewrtqwropethert".into()),
Tag::String("asdf".into()),
Tag::String("alsdkjiqwoe".into()),
Tag::String("lmqi9hyqd".into()),
Tag::String("qwertyuiop".into()),
Tag::String("asdfghjkl".into()),
Tag::String("zxcvbnm".into()),
Tag::String(" ".into()),
Tag::String("words words words words words words".into()),
Tag::String("aaaaaaaaaaaaaaaaaaaa".into()),
Tag::String("".into()),
Tag::String("a\nb\n\n\nc\r\rd".into()),
Tag::String("😁".into()),
])
)]));
let original = include_bytes!("stringtest.nbt").to_vec();