1
0
Fork 0
mirror of https://github.com/azalea-rs/simdnbt.git synced 2025-08-02 07:26:04 +00:00

make FromNbtTag take simdnbt::borrow::NbtTag

This commit is contained in:
mat 2023-11-28 20:16:18 -06:00
parent e2864bcf12
commit d10fa0fc38
6 changed files with 122 additions and 42 deletions

View file

@ -34,7 +34,7 @@ pub fn deserialize_derive(input: proc_macro::TokenStream) -> proc_macro::TokenSt
field_deserializers.push(quote! { field_deserializers.push(quote! {
#struct_field_name: simdnbt::FromNbtTag::from_optional_nbt_tag( #struct_field_name: simdnbt::FromNbtTag::from_optional_nbt_tag(
nbt.take(#field_name) nbt.get(#field_name)
)?.ok_or(simdnbt::DeserializeError::MismatchedFieldType(#debug_ident.to_owned()))? )?.ok_or(simdnbt::DeserializeError::MismatchedFieldType(#debug_ident.to_owned()))?
}); });
} }
@ -64,7 +64,7 @@ pub fn deserialize_derive(input: proc_macro::TokenStream) -> proc_macro::TokenSt
let output = quote! { let output = quote! {
impl #generics simdnbt::Deserialize for #ident #generics #where_clause { impl #generics simdnbt::Deserialize for #ident #generics #where_clause {
fn from_compound(mut nbt: simdnbt::owned::NbtCompound) -> Result<Self, simdnbt::DeserializeError> { fn from_compound(mut nbt: &simdnbt::borrow::NbtCompound) -> Result<Self, simdnbt::DeserializeError> {
let value = Self { let value = Self {
#(#field_deserializers),* #(#field_deserializers),*
}; };
@ -168,7 +168,7 @@ pub fn from_nbt_tag_derive(input: proc_macro::TokenStream) -> proc_macro::TokenS
let output = quote! { let output = quote! {
impl #generics simdnbt::FromNbtTag for #ident #generics #where_clause { impl #generics simdnbt::FromNbtTag for #ident #generics #where_clause {
fn from_nbt_tag(tag: simdnbt::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &simdnbt::borrow::NbtTag) -> Option<Self> {
match tag.string()?.to_str().as_ref() { match tag.string()?.to_str().as_ref() {
#(#matchers)* #(#matchers)*
_ => None, _ => None,

View file

@ -1,6 +1,6 @@
use std::{collections::HashMap, hint::black_box, io::Cursor}; use std::{collections::HashMap, hint::black_box, io::Cursor};
use simdnbt::{owned::Nbt, Deserialize, Serialize}; use simdnbt::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct Item { pub struct Item {
@ -68,13 +68,18 @@ fn main() {
let input = black_box(include_bytes!("../tests/realworld.nbt")); let input = black_box(include_bytes!("../tests/realworld.nbt"));
for _ in 0..1 { for _ in 0..1 {
let nbt = Nbt::read(&mut Cursor::new(input)); let nbt = simdnbt::borrow::Nbt::read(&mut Cursor::new(input));
let nbt = black_box(nbt.unwrap().unwrap()); let nbt = black_box(nbt.unwrap().unwrap());
let data = Base::from_nbt(nbt).unwrap(); let data = Base::from_nbt(&nbt).unwrap();
// roundtrip // roundtrip
let new_data = Base::from_nbt(data.clone().to_nbt()).unwrap(); let mut new_nbt_bytes = Vec::new();
data.clone().to_nbt().write(&mut new_nbt_bytes);
let new_nbt = simdnbt::borrow::Nbt::read(&mut Cursor::new(&new_nbt_bytes[..]))
.unwrap()
.unwrap();
let new_data = Base::from_nbt(&new_nbt).unwrap();
assert_eq!(data, new_data); assert_eq!(data, new_data);
println!("data: {:?}", data.items); println!("data: {:?}", data.items);

View file

@ -21,6 +21,10 @@ pub struct NbtCompound<'a> {
} }
impl<'a> NbtCompound<'a> { impl<'a> NbtCompound<'a> {
pub fn from_values(values: Vec<(&'a Mutf8Str, NbtTag<'a>)>) -> Self {
Self { values }
}
pub fn read(data: &mut Cursor<&'a [u8]>) -> Result<Self, Error> { pub fn read(data: &mut Cursor<&'a [u8]>) -> Result<Self, Error> {
Self::read_with_depth(data, 0) Self::read_with_depth(data, 0)
} }
@ -204,4 +208,20 @@ impl<'a> NbtCompound<'a> {
pub fn iter(&self) -> impl Iterator<Item = (&Mutf8Str, &NbtTag<'a>)> { pub fn iter(&self) -> impl Iterator<Item = (&Mutf8Str, &NbtTag<'a>)> {
self.values.iter().map(|(k, v)| (*k, v)) self.values.iter().map(|(k, v)| (*k, v))
} }
pub fn len(&self) -> usize {
self.values.len()
}
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
pub fn to_owned(&self) -> crate::owned::NbtCompound {
crate::owned::NbtCompound {
values: self
.values
.iter()
.map(|(k, v)| ((*k).to_owned(), v.to_owned()))
.collect(),
}
}
} }

View file

@ -265,4 +265,43 @@ impl<'a> NbtList<'a> {
_ => None, _ => None,
} }
} }
pub fn to_owned(&self) -> crate::owned::NbtList {
match self {
NbtList::Empty => crate::owned::NbtList::Empty,
NbtList::Byte(bytes) => crate::owned::NbtList::Byte(bytes.to_vec()),
NbtList::Short(shorts) => crate::owned::NbtList::Short(shorts.to_vec()),
NbtList::Int(ints) => crate::owned::NbtList::Int(ints.to_vec()),
NbtList::Long(longs) => crate::owned::NbtList::Long(longs.to_vec()),
NbtList::Float(floats) => crate::owned::NbtList::Float(floats.to_vec()),
NbtList::Double(doubles) => crate::owned::NbtList::Double(doubles.to_vec()),
NbtList::ByteArray(byte_arrays) => crate::owned::NbtList::ByteArray(
byte_arrays.iter().map(|array| array.to_vec()).collect(),
),
NbtList::String(strings) => crate::owned::NbtList::String(
strings.iter().map(|&string| string.to_owned()).collect(),
),
NbtList::List(lists) => {
crate::owned::NbtList::List(lists.iter().map(|list| list.to_owned()).collect())
}
NbtList::Compound(compounds) => crate::owned::NbtList::Compound(
compounds
.iter()
.map(|compound| compound.to_owned())
.collect(),
),
NbtList::IntArray(int_arrays) => crate::owned::NbtList::IntArray(
int_arrays
.iter()
.map(|array| array.to_vec())
.collect::<Vec<_>>(),
),
NbtList::LongArray(long_arrays) => crate::owned::NbtList::LongArray(
long_arrays
.iter()
.map(|array| array.to_vec())
.collect::<Vec<_>>(),
),
}
}
} }

View file

@ -200,6 +200,23 @@ impl<'a> NbtTag<'a> {
_ => None, _ => None,
} }
} }
pub fn to_owned(&self) -> crate::owned::NbtTag {
match self {
NbtTag::Byte(byte) => crate::owned::NbtTag::Byte(*byte),
NbtTag::Short(short) => crate::owned::NbtTag::Short(*short),
NbtTag::Int(int) => crate::owned::NbtTag::Int(*int),
NbtTag::Long(long) => crate::owned::NbtTag::Long(*long),
NbtTag::Float(float) => crate::owned::NbtTag::Float(*float),
NbtTag::Double(double) => crate::owned::NbtTag::Double(*double),
NbtTag::ByteArray(byte_array) => crate::owned::NbtTag::ByteArray(byte_array.to_vec()),
NbtTag::String(string) => crate::owned::NbtTag::String((*string).to_owned()),
NbtTag::List(list) => crate::owned::NbtTag::List(list.to_owned()),
NbtTag::Compound(compound) => crate::owned::NbtTag::Compound(compound.to_owned()),
NbtTag::IntArray(int_array) => crate::owned::NbtTag::IntArray(int_array.to_vec()),
NbtTag::LongArray(long_array) => crate::owned::NbtTag::LongArray(long_array.to_vec()),
}
}
} }
#[cfg(test)] #[cfg(test)]

View file

@ -3,11 +3,11 @@ use std::{collections::HashMap, fmt::Display, hash::Hash, str::FromStr};
use crate::DeserializeError; use crate::DeserializeError;
pub trait Deserialize: Sized { pub trait Deserialize: Sized {
fn from_nbt(nbt: crate::owned::BaseNbt) -> Result<Self, DeserializeError> { fn from_nbt(nbt: &crate::borrow::BaseNbt) -> Result<Self, DeserializeError> {
Self::from_compound(nbt.into_inner()) Self::from_compound(nbt)
} }
fn from_compound(compound: crate::owned::NbtCompound) -> Result<Self, DeserializeError>; fn from_compound(compound: &crate::borrow::NbtCompound) -> Result<Self, DeserializeError>;
} }
pub trait Serialize: Sized { pub trait Serialize: Sized {
@ -19,9 +19,9 @@ pub trait Serialize: Sized {
} }
pub trait FromNbtTag: Sized { pub trait FromNbtTag: Sized {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self>; fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self>;
fn from_optional_nbt_tag( fn from_optional_nbt_tag(
tag: Option<crate::owned::NbtTag>, tag: Option<&crate::borrow::NbtTag>,
) -> Result<Option<Self>, DeserializeError> { ) -> Result<Option<Self>, DeserializeError> {
match tag { match tag {
Some(tag) => Ok(Self::from_nbt_tag(tag)), Some(tag) => Ok(Self::from_nbt_tag(tag)),
@ -38,10 +38,10 @@ pub trait ToNbtTag: Sized {
} }
impl<K: Display + FromStr + Eq + Hash, V: FromNbtTag> Deserialize for HashMap<K, V> { impl<K: Display + FromStr + Eq + Hash, V: FromNbtTag> Deserialize for HashMap<K, V> {
fn from_compound(compound: crate::owned::NbtCompound) -> Result<Self, DeserializeError> { fn from_compound(compound: &crate::borrow::NbtCompound) -> Result<Self, DeserializeError> {
let mut hashmap = HashMap::with_capacity(compound.values.len()); let mut hashmap = HashMap::with_capacity(compound.len());
for (k, v) in compound.values { for (k, v) in compound.iter() {
let k_str = k.to_str(); let k_str = k.to_str();
let k_parsed = k_str let k_parsed = k_str
.parse() .parse()
@ -70,8 +70,8 @@ impl<K: Display + FromStr + Eq + Hash, V: ToNbtTag> Serialize for HashMap<K, V>
} }
impl Deserialize for crate::owned::NbtCompound { impl Deserialize for crate::owned::NbtCompound {
fn from_compound(compound: crate::owned::NbtCompound) -> Result<Self, DeserializeError> { fn from_compound(compound: &crate::borrow::NbtCompound) -> Result<Self, DeserializeError> {
Ok(compound) Ok(compound.to_owned())
} }
} }
impl Serialize for crate::owned::NbtCompound { impl Serialize for crate::owned::NbtCompound {
@ -81,9 +81,8 @@ impl Serialize for crate::owned::NbtCompound {
} }
impl<T: Deserialize> FromNbtTag for T { impl<T: Deserialize> FromNbtTag for T {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.into_compound() tag.compound().and_then(|c| Self::from_compound(c).ok())
.and_then(|c| Self::from_compound(c).ok())
} }
} }
@ -94,8 +93,8 @@ impl<T: Serialize> ToNbtTag for T {
} }
impl FromNbtTag for crate::owned::NbtTag { impl FromNbtTag for crate::owned::NbtTag {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
Some(tag) Some(tag.to_owned())
} }
} }
impl ToNbtTag for crate::owned::NbtTag { impl ToNbtTag for crate::owned::NbtTag {
@ -106,7 +105,7 @@ impl ToNbtTag for crate::owned::NbtTag {
// standard nbt types // standard nbt types
impl FromNbtTag for i8 { impl FromNbtTag for i8 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.byte() tag.byte()
} }
} }
@ -117,7 +116,7 @@ impl ToNbtTag for i8 {
} }
impl FromNbtTag for i16 { impl FromNbtTag for i16 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.short() tag.short()
} }
} }
@ -128,7 +127,7 @@ impl ToNbtTag for i16 {
} }
impl FromNbtTag for i32 { impl FromNbtTag for i32 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.int() tag.int()
} }
} }
@ -139,7 +138,7 @@ impl ToNbtTag for i32 {
} }
impl FromNbtTag for i64 { impl FromNbtTag for i64 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.long() tag.long()
} }
} }
@ -150,7 +149,7 @@ impl ToNbtTag for i64 {
} }
impl FromNbtTag for f32 { impl FromNbtTag for f32 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.float() tag.float()
} }
} }
@ -161,7 +160,7 @@ impl ToNbtTag for f32 {
} }
impl FromNbtTag for f64 { impl FromNbtTag for f64 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.double() tag.double()
} }
} }
@ -172,7 +171,7 @@ impl ToNbtTag for f64 {
} }
impl FromNbtTag for String { impl FromNbtTag for String {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.string().map(|s| s.to_string()) tag.string().map(|s| s.to_string())
} }
} }
@ -184,7 +183,7 @@ impl ToNbtTag for String {
// unsigned integers // unsigned integers
impl FromNbtTag for u8 { impl FromNbtTag for u8 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.byte().map(|b| b as u8) tag.byte().map(|b| b as u8)
} }
} }
@ -195,7 +194,7 @@ impl ToNbtTag for u8 {
} }
impl FromNbtTag for u16 { impl FromNbtTag for u16 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.short().map(|s| s as u16) tag.short().map(|s| s as u16)
} }
} }
@ -206,7 +205,7 @@ impl ToNbtTag for u16 {
} }
impl FromNbtTag for u32 { impl FromNbtTag for u32 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.int().map(|i| i as u32) tag.int().map(|i| i as u32)
} }
} }
@ -217,7 +216,7 @@ impl ToNbtTag for u32 {
} }
impl FromNbtTag for u64 { impl FromNbtTag for u64 {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.long().map(|l| l as u64) tag.long().map(|l| l as u64)
} }
} }
@ -229,7 +228,7 @@ impl ToNbtTag for u64 {
// lists // lists
impl FromNbtTag for Vec<String> { impl FromNbtTag for Vec<String> {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.list().and_then(|l| { tag.list().and_then(|l| {
l.strings() l.strings()
.map(|s| s.iter().map(|s| s.to_string()).collect()) .map(|s| s.iter().map(|s| s.to_string()).collect())
@ -246,11 +245,11 @@ impl ToNbtTag for Vec<String> {
// slightly less standard types // slightly less standard types
impl<T: FromNbtTag> FromNbtTag for Option<T> { impl<T: FromNbtTag> FromNbtTag for Option<T> {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
Some(T::from_nbt_tag(tag)) Some(T::from_nbt_tag(tag))
} }
fn from_optional_nbt_tag( fn from_optional_nbt_tag(
tag: Option<crate::owned::NbtTag>, tag: Option<&crate::borrow::NbtTag>,
) -> Result<Option<Self>, DeserializeError> { ) -> Result<Option<Self>, DeserializeError> {
match tag { match tag {
Some(tag) => Ok(Some(T::from_nbt_tag(tag))), Some(tag) => Ok(Some(T::from_nbt_tag(tag))),
@ -269,11 +268,11 @@ impl<T: ToNbtTag> ToNbtTag for Option<T> {
impl<T: Deserialize> FromNbtTag for Vec<Option<T>> { impl<T: Deserialize> FromNbtTag for Vec<Option<T>> {
/// A list of compounds where `None` is an empty compound /// A list of compounds where `None` is an empty compound
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
let list = tag.into_list()?.into_compounds()?; let list = tag.list()?.compounds()?;
let mut vec = Vec::with_capacity(list.len()); let mut vec = Vec::with_capacity(list.len());
for tag in list { for tag in list {
if tag.values.is_empty() { if tag.is_empty() {
vec.push(None); vec.push(None);
} else { } else {
vec.push(Some(T::from_compound(tag).ok()?)); vec.push(Some(T::from_compound(tag).ok()?));
@ -297,8 +296,8 @@ impl<T: Serialize> ToNbtTag for Vec<Option<T>> {
} }
impl<T: Deserialize> FromNbtTag for Vec<T> { impl<T: Deserialize> FromNbtTag for Vec<T> {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
let list = tag.into_list()?.into_compounds()?; let list = tag.list()?.compounds()?;
let mut vec = Vec::with_capacity(list.len()); let mut vec = Vec::with_capacity(list.len());
for tag in list { for tag in list {
vec.push(T::from_compound(tag).ok()?); vec.push(T::from_compound(tag).ok()?);
@ -316,7 +315,7 @@ impl<T: Serialize> ToNbtTag for Vec<T> {
} }
impl FromNbtTag for bool { impl FromNbtTag for bool {
fn from_nbt_tag(tag: crate::owned::NbtTag) -> Option<Self> { fn from_nbt_tag(tag: &crate::borrow::NbtTag) -> Option<Self> {
tag.byte().map(|b| b != 0) tag.byte().map(|b| b != 0)
} }
} }