na_nbt 0.2.1

High-performance NBT (Named Binary Tag) library with zero-copy parsing and serde support
Documentation
mod array;
mod compound;
mod config;
mod document;
mod list;
mod mark;
mod read;
mod size;
mod string;
mod typed_list;
mod value;
mod write;

mod borrowed {
    use zerocopy::byteorder;

    use crate::{
        ByteOrder, ConfigRef, Result, TagID, cold_path,
        immutable::{config::ImmutableConfig, document::Document},
    };

    use super::*;

    pub type BorrowedValue<'s, O> = value::ReadonlyValue<'s, O, ()>;

    impl Document for () {
        fn empty() -> Self {}
    }

    pub fn read_borrowed<'s, O: ByteOrder>(source: &'s [u8]) -> Result<BorrowedDocument<'s, O>> {
        unsafe {
            read::read_unsafe::<O, _>(source.as_ptr(), source.len(), |mark| BorrowedDocument {
                mark,
                source: source.as_ptr(),
                _marker: core::marker::PhantomData::<(&'s (), O)>,
            })
        }
    }

    pub struct BorrowedDocument<'s, O: ByteOrder> {
        mark: Vec<mark::Mark>,
        source: *const u8,
        _marker: core::marker::PhantomData<(&'s (), O)>,
    }

    impl<'s, O: ByteOrder> BorrowedDocument<'s, O> {
        #[inline]
        pub fn root<'doc>(&'doc self) -> BorrowedValue<'doc, O> {
            let root_tag = unsafe { *self.source.cast() };

            if root_tag == TagID::End {
                cold_path();
                return BorrowedValue::End(());
            }

            let name_len =
                byteorder::U16::<O>::from_bytes(unsafe { *self.source.add(1).cast() }).get();

            unsafe {
                <ImmutableConfig<O, ()> as ConfigRef>::read_value(
                    root_tag,
                    (
                        self.source.add(3 + name_len as usize),
                        self.mark.as_ptr(),
                        &(),
                    ),
                )
            }
        }
    }

    unsafe impl<'s, O: ByteOrder> Send for BorrowedDocument<'s, O> {}
    unsafe impl<'s, O: ByteOrder> Sync for BorrowedDocument<'s, O> {}
}

pub use borrowed::read_borrowed;

#[cfg(feature = "shared")]
mod shared {
    use std::sync::Arc;

    use bytes::Bytes;
    use zerocopy::byteorder;

    use crate::{
        ByteOrder, ConfigRef, Result, TagID, cold_path,
        immutable::{config::ImmutableConfig, document::Document},
    };

    use super::*;

    pub type SharedValue<O> = value::ReadonlyValue<'static, O, Arc<SharedDocument>>;

    impl Document for Arc<SharedDocument> {
        fn empty() -> Self {
            Arc::new(SharedDocument {
                mark: Vec::new(),
                source: Bytes::new(),
            })
        }
    }

    pub fn read_shared<O: ByteOrder>(source: Bytes) -> Result<SharedValue<O>> {
        Ok(unsafe {
            read::read_unsafe::<O, _>(source.as_ptr(), source.len(), |mark| {
                Arc::new(SharedDocument { mark, source })
            })?
            .root()
        })
    }

    /// A parsed NBT document with shared ownership.
    ///
    /// This type holds the source data and parsing metadata for [`SharedValue`]s.
    /// It is managed through `Arc` and should not typically be used directly.
    pub struct SharedDocument {
        mark: Vec<mark::Mark>,
        source: Bytes,
    }

    impl SharedDocument {
        /// Returns the root value of the document.
        #[inline]
        pub fn root<O: ByteOrder>(self: Arc<Self>) -> SharedValue<O> {
            let root_tag = unsafe { TagID::from_u8_unchecked(*self.source.get_unchecked(0)) };

            if root_tag == TagID::End {
                cold_path();
                return SharedValue::End(());
            }

            let name_len =
                byteorder::U16::<O>::from_bytes(unsafe { *self.source.as_ptr().add(1).cast() })
                    .get();

            unsafe {
                <ImmutableConfig<O, Arc<SharedDocument>> as ConfigRef>::read_value(
                    root_tag,
                    (
                        self.source.as_ptr().add(3 + name_len as usize),
                        self.mark.as_ptr(),
                        &self,
                    ),
                )
            }
        }
    }
}

#[cfg(feature = "shared")]
pub use shared::read_shared;