na_nbt 0.2.1

High-performance NBT (Named Binary Tag) library with zero-copy parsing and serde support
Documentation
use std::{marker::PhantomData, mem::ManuallyDrop, ptr};

use zerocopy::byteorder;

use crate::{
    ByteOrder, CompoundOwn, ListOwn, NBT, NBTBase, StringOwn, TypedListOwn, VecOwn,
    tag::{
        Byte, ByteArray, Compound, Double, Float, Int, IntArray, List, Long, LongArray, Short,
        String,
    },
};

pub trait IntoNBT<O: ByteOrder> {
    type Tag: NBT;

    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O>;
}

impl<O: ByteOrder> IntoNBT<O> for i8 {
    type Tag = Byte;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}

impl<O: ByteOrder> IntoNBT<O> for i16 {
    type Tag = Short;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::I16::<O>::new(self)
    }
}

impl<O: ByteOrder, R: ByteOrder> IntoNBT<O> for byteorder::I16<R> {
    type Tag = Short;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::I16::<O>::new(self.get())
    }
}

impl<O: ByteOrder> IntoNBT<O> for i32 {
    type Tag = Int;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::I32::<O>::new(self)
    }
}

impl<O: ByteOrder, R: ByteOrder> IntoNBT<O> for byteorder::I32<R> {
    type Tag = Int;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::I32::<O>::new(self.get())
    }
}

impl<O: ByteOrder> IntoNBT<O> for i64 {
    type Tag = Long;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::I64::<O>::new(self)
    }
}

impl<O: ByteOrder, R: ByteOrder> IntoNBT<O> for byteorder::I64<R> {
    type Tag = Long;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::I64::<O>::new(self.get())
    }
}

impl<O: ByteOrder> IntoNBT<O> for f32 {
    type Tag = Float;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::F32::<O>::new(self)
    }
}

impl<O: ByteOrder, R: ByteOrder> IntoNBT<O> for byteorder::F32<R> {
    type Tag = Float;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::F32::<O>::new(self.get())
    }
}

impl<O: ByteOrder> IntoNBT<O> for f64 {
    type Tag = Double;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::F64::<O>::new(self)
    }
}

impl<O: ByteOrder, R: ByteOrder> IntoNBT<O> for byteorder::F64<R> {
    type Tag = Double;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        byteorder::F64::<O>::new(self.get())
    }
}

impl<O: ByteOrder> IntoNBT<O> for Vec<i8> {
    type Tag = ByteArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for &[i8] {
    type Tag = ByteArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder, const N: usize> IntoNBT<O> for [i8; N] {
    type Tag = ByteArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.as_slice().into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for VecOwn<i8> {
    type Tag = ByteArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}

impl<O: ByteOrder> IntoNBT<O> for std::string::String {
    type Tag = String;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for &str {
    type Tag = String;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for StringOwn {
    type Tag = String;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}

impl<O: ByteOrder> IntoNBT<O> for ListOwn<O> {
    type Tag = List;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}

impl<O: ByteOrder, T: NBT> IntoNBT<O> for TypedListOwn<O, T> {
    type Tag = List;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        let me = ManuallyDrop::new(self);
        ListOwn {
            data: unsafe { ptr::read(&me.data) },
            _marker: PhantomData,
        }
    }
}

impl<O: ByteOrder> IntoNBT<O> for CompoundOwn<O> {
    type Tag = Compound;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}

impl<O: ByteOrder> IntoNBT<O> for Vec<byteorder::I32<O>> {
    type Tag = IntArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for &[byteorder::I32<O>] {
    type Tag = IntArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder, const N: usize> IntoNBT<O> for [byteorder::I32<O>; N] {
    type Tag = IntArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.as_slice().into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for VecOwn<byteorder::I32<O>> {
    type Tag = IntArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}

impl<O: ByteOrder> IntoNBT<O> for Vec<byteorder::I64<O>> {
    type Tag = LongArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for &[byteorder::I64<O>] {
    type Tag = LongArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.into()
    }
}

impl<O: ByteOrder, const N: usize> IntoNBT<O> for [byteorder::I64<O>; N] {
    type Tag = LongArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self.as_slice().into()
    }
}

impl<O: ByteOrder> IntoNBT<O> for VecOwn<byteorder::I64<O>> {
    type Tag = LongArray;

    #[inline]
    fn into_nbt(self) -> <Self::Tag as NBTBase>::Type<O> {
        self
    }
}