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! {
#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()))?
});
}
@ -64,7 +64,7 @@ pub fn deserialize_derive(input: proc_macro::TokenStream) -> proc_macro::TokenSt
let output = quote! {
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 {
#(#field_deserializers),*
};
@ -168,7 +168,7 @@ pub fn from_nbt_tag_derive(input: proc_macro::TokenStream) -> proc_macro::TokenS
let output = quote! {
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() {
#(#matchers)*
_ => None,

View file

@ -1,6 +1,6 @@
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)]
pub struct Item {
@ -68,13 +68,18 @@ fn main() {
let input = black_box(include_bytes!("../tests/realworld.nbt"));
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 data = Base::from_nbt(nbt).unwrap();
let data = Base::from_nbt(&nbt).unwrap();
// 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);
println!("data: {:?}", data.items);

View file

@ -21,6 +21,10 @@ pub struct 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> {
Self::read_with_depth(data, 0)
}
@ -204,4 +208,20 @@ impl<'a> NbtCompound<'a> {
pub fn iter(&self) -> impl Iterator<Item = (&Mutf8Str, &NbtTag<'a>)> {
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,
}
}
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,
}
}
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)]

View file

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