na_nbt 0.2.1

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

use zerocopy::byteorder;

use crate::{
    ByteOrder, MapMut, StringMut, VecMut, NBT, TagID, ValueBase, ValueMut, VisitMut,
    VisitMutShared,
    mutable::{
        compound_mut::MutCompound, compound_ref::RefCompound, config::MutableConfig,
        list_mut::MutList, list_ref::RefList, string_ref::RefString, typed_list_mut::MutTypedList,
        value_ref::RefValue,
    },
};

pub enum MutValue<'s, O: ByteOrder> {
    End(&'s mut ()),
    Byte(&'s mut i8),
    Short(&'s mut byteorder::I16<O>),
    Int(&'s mut byteorder::I32<O>),
    Long(&'s mut byteorder::I64<O>),
    Float(&'s mut byteorder::F32<O>),
    Double(&'s mut byteorder::F64<O>),
    ByteArray(VecMut<'s, i8>),
    String(StringMut<'s>),
    List(MutList<'s, O>),
    Compound(MutCompound<'s, O>),
    IntArray(VecMut<'s, byteorder::I32<O>>),
    LongArray(VecMut<'s, byteorder::I64<O>>),
}

impl<'s, O: ByteOrder> ValueBase for MutValue<'s, O> {
    #[inline]
    fn tag_id(&self) -> TagID {
        match self {
            MutValue::End(_) => TagID::End,
            MutValue::Byte(_) => TagID::Byte,
            MutValue::Short(_) => TagID::Short,
            MutValue::Int(_) => TagID::Int,
            MutValue::Long(_) => TagID::Long,
            MutValue::Float(_) => TagID::Float,
            MutValue::Double(_) => TagID::Double,
            MutValue::ByteArray(_) => TagID::ByteArray,
            MutValue::String(_) => TagID::String,
            MutValue::List(_) => TagID::List,
            MutValue::Compound(_) => TagID::Compound,
            MutValue::IntArray(_) => TagID::IntArray,
            MutValue::LongArray(_) => TagID::LongArray,
        }
    }
}

impl<'s, O: ByteOrder> ValueMut<'s> for MutValue<'s, O> {
    type Config = MutableConfig<O>;

    fn visit_shared<'a, R>(
        &'a self,
        match_fn: impl FnOnce(VisitMutShared<'a, 's, Self::Config>) -> R,
    ) -> R
    where
        's: 'a,
    {
        match self {
            MutValue::End(value) => match_fn(VisitMutShared::End(value)),
            MutValue::Byte(value) => match_fn(VisitMutShared::Byte(value)),
            MutValue::Short(value) => match_fn(VisitMutShared::Short(value)),
            MutValue::Int(value) => match_fn(VisitMutShared::Int(value)),
            MutValue::Long(value) => match_fn(VisitMutShared::Long(value)),
            MutValue::Float(value) => match_fn(VisitMutShared::Float(value)),
            MutValue::Double(value) => match_fn(VisitMutShared::Double(value)),
            MutValue::ByteArray(value) => match_fn(VisitMutShared::ByteArray(value)),
            MutValue::String(value) => match_fn(VisitMutShared::String(value)),
            MutValue::List(value) => match_fn(VisitMutShared::List(value)),
            MutValue::Compound(value) => match_fn(VisitMutShared::Compound(value)),
            MutValue::IntArray(value) => match_fn(VisitMutShared::IntArray(value)),
            MutValue::LongArray(value) => match_fn(VisitMutShared::LongArray(value)),
        }
    }

    fn visit<'a, R>(&'a mut self, match_fn: impl FnOnce(VisitMut<'a, 's, Self::Config>) -> R) -> R
    where
        's: 'a,
    {
        match self {
            MutValue::End(value) => match_fn(VisitMut::End(value)),
            MutValue::Byte(value) => match_fn(VisitMut::Byte(value)),
            MutValue::Short(value) => match_fn(VisitMut::Short(value)),
            MutValue::Int(value) => match_fn(VisitMut::Int(value)),
            MutValue::Long(value) => match_fn(VisitMut::Long(value)),
            MutValue::Float(value) => match_fn(VisitMut::Float(value)),
            MutValue::Double(value) => match_fn(VisitMut::Double(value)),
            MutValue::ByteArray(value) => match_fn(VisitMut::ByteArray(value)),
            MutValue::String(value) => match_fn(VisitMut::String(value)),
            MutValue::List(value) => match_fn(VisitMut::List(value)),
            MutValue::Compound(value) => match_fn(VisitMut::Compound(value)),
            MutValue::IntArray(value) => match_fn(VisitMut::IntArray(value)),
            MutValue::LongArray(value) => match_fn(VisitMut::LongArray(value)),
        }
    }

    fn map<R>(self, match_fn: impl FnOnce(MapMut<'s, Self::Config>) -> R) -> R {
        match self {
            MutValue::End(value) => match_fn(MapMut::End(value)),
            MutValue::Byte(value) => match_fn(MapMut::Byte(value)),
            MutValue::Short(value) => match_fn(MapMut::Short(value)),
            MutValue::Int(value) => match_fn(MapMut::Int(value)),
            MutValue::Long(value) => match_fn(MapMut::Long(value)),
            MutValue::Float(value) => match_fn(MapMut::Float(value)),
            MutValue::Double(value) => match_fn(MapMut::Double(value)),
            MutValue::ByteArray(value) => match_fn(MapMut::ByteArray(value)),
            MutValue::String(value) => match_fn(MapMut::String(value)),
            MutValue::List(value) => match_fn(MapMut::List(value)),
            MutValue::Compound(value) => match_fn(MapMut::Compound(value)),
            MutValue::IntArray(value) => match_fn(MapMut::IntArray(value)),
            MutValue::LongArray(value) => match_fn(MapMut::LongArray(value)),
        }
    }

    #[allow(clippy::unit_arg)]
    fn to_ref<'a>(&'a self) -> RefValue<'a, O> {
        match self {
            MutValue::End(value) => RefValue::End(**value),
            MutValue::Byte(value) => RefValue::Byte(**value),
            MutValue::Short(value) => RefValue::Short(value.get()),
            MutValue::Int(value) => RefValue::Int(value.get()),
            MutValue::Long(value) => RefValue::Long(value.get()),
            MutValue::Float(value) => RefValue::Float(value.get()),
            MutValue::Double(value) => RefValue::Double(value.get()),
            MutValue::ByteArray(value) => RefValue::ByteArray(value),
            MutValue::String(value) => RefValue::String(RefString {
                data: value.as_mutf8_str(),
            }),
            MutValue::List(value) => RefValue::List(RefList {
                data: value.data.as_ptr(),
                _marker: PhantomData,
            }),
            MutValue::Compound(value) => RefValue::Compound(RefCompound {
                data: value.data.as_ptr(),
                _marker: PhantomData,
            }),
            MutValue::IntArray(value) => RefValue::IntArray(value),
            MutValue::LongArray(value) => RefValue::LongArray(value),
        }
    }
}

impl<'s, O: ByteOrder> From<&'s mut ()> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut ()) -> Self {
        MutValue::End(value)
    }
}

impl<'s, O: ByteOrder> From<&'s mut i8> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut i8) -> Self {
        MutValue::Byte(value)
    }
}

impl<'s, O: ByteOrder> From<&'s mut byteorder::I16<O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut byteorder::I16<O>) -> Self {
        MutValue::Short(value)
    }
}

impl<'s, O: ByteOrder> From<&'s mut byteorder::I32<O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut byteorder::I32<O>) -> Self {
        MutValue::Int(value)
    }
}

impl<'s, O: ByteOrder> From<&'s mut byteorder::I64<O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut byteorder::I64<O>) -> Self {
        MutValue::Long(value)
    }
}

impl<'s, O: ByteOrder> From<&'s mut byteorder::F32<O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut byteorder::F32<O>) -> Self {
        MutValue::Float(value)
    }
}

impl<'s, O: ByteOrder> From<&'s mut byteorder::F64<O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: &'s mut byteorder::F64<O>) -> Self {
        MutValue::Double(value)
    }
}

impl<'s, O: ByteOrder> From<VecMut<'s, i8>> for MutValue<'s, O> {
    #[inline]
    fn from(value: VecMut<'s, i8>) -> Self {
        MutValue::ByteArray(value)
    }
}

impl<'s, O: ByteOrder> From<StringMut<'s>> for MutValue<'s, O> {
    #[inline]
    fn from(value: StringMut<'s>) -> Self {
        MutValue::String(value)
    }
}

impl<'s, O: ByteOrder> From<MutList<'s, O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: MutList<'s, O>) -> Self {
        MutValue::List(value)
    }
}

impl<'s, O: ByteOrder> From<MutCompound<'s, O>> for MutValue<'s, O> {
    #[inline]
    fn from(value: MutCompound<'s, O>) -> Self {
        MutValue::Compound(value)
    }
}

impl<'s, O: ByteOrder> From<VecMut<'s, byteorder::I32<O>>> for MutValue<'s, O> {
    #[inline]
    fn from(value: VecMut<'s, byteorder::I32<O>>) -> Self {
        MutValue::IntArray(value)
    }
}

impl<'s, O: ByteOrder> From<VecMut<'s, byteorder::I64<O>>> for MutValue<'s, O> {
    #[inline]
    fn from(value: VecMut<'s, byteorder::I64<O>>) -> Self {
        MutValue::LongArray(value)
    }
}

impl<'s, O: ByteOrder, T: NBT> From<MutTypedList<'s, O, T>> for MutValue<'s, O> {
    #[inline]
    fn from(value: MutTypedList<'s, O, T>) -> Self {
        MutValue::List(MutList {
            data: value.data,
            _marker: PhantomData,
        })
    }
}