Crate na_nbt

Crate na_nbt 

Source
Expand description

§na_nbt

A high-performance NBT (Named Binary Tag) parser with serde support. NBT is a binary format used by Minecraft.

§Operating on untyped NBT values

There are three ways to parse NBT values:

  1. Borrowed: read_borrowed - Zero-copy reading from a borrowed slice.
use na_nbt::{BE, ValueRef, read_borrowed, tag};
let data = include_bytes!("../fuzz/in/level");
let doc = read_borrowed::<BE>(data).unwrap();
let nbt = doc.root();
let o = nbt
    .get("Data")
    .and_then(|d| d.get("Player"))
    .and_then(|p| p.get("Attributes"))
    .and_then(|a| a.get(2))
    .and_then(|a| a.get("Modifiers"))
    .and_then(|m| m.get(0))
    .and_then(|m| m.get_::<tag::Int>("Operation"))
    // or:
    //  .and_then(|m| m.get("Operation"))
    //  .and_then(|o| o.into_::<tag::Int>())
    .unwrap();
assert_eq!(o, 2);

There is a constraint that doc must not outlive the source, and nbt must not outlive doc.

  1. Shared: read_shared - Zero-copy reading from a bytes::Bytes with shared ownership.
use na_nbt::{BE, ValueRef, read_shared, tag};
let data = include_bytes!("../fuzz/in/level");
let nbt = read_shared::<BE>(bytes::Bytes::copy_from_slice(data)).unwrap();
let player = nbt
    .get("Data")
    .and_then(|d| d.get_::<tag::Compound>("Player"))
    .unwrap();

Similar to borrowed, but there is not a doc, and nbt’s lifetime is not tied to the source.

  1. Owned: read_owned - Parses NBT into fully owned structures that can be modified.
use na_nbt::{BE, ValueMut, Writable, read_owned, tag};
let data = include_bytes!("../fuzz/in/level");
let mut nbt = read_owned::<BE, BE>(data).unwrap();
let mut data = nbt.get_mut("Data").unwrap();
let mut player = data.get_mut("Player").unwrap();
player.get_mut("Health").unwrap().into_::<tag::Short>().unwrap().set(10);
player.get_mut_::<tag::Short>("Health").unwrap().set(10);
*player.get_mut_::<tag::Byte>("Sleeping").unwrap() = 1;
let file = std::fs::File::create("new.nbt").unwrap();
nbt.write_to_writer::<BE>(file).unwrap();

§Generic functions and constructing NBT values

There are three groups of traits and structs provided to write generic functions and construct NBT values.

in fact, methods on the result of read_xxx are provided by these traits.

  1. Ref: ValueRef, ListRef, CompoundRef and TypedListRef.
  2. Mut: ValueMut, ListMut, CompoundMut and TypedListMut.
  3. Own: ValueOwn, ListOwn, CompoundOwn and TypedListOwn.
use na_nbt::{CompoundMut, CompoundOwn, TypedListOwn};
 
fn example<'s>(nbt: &mut impl CompoundMut<'s>) {
    let mut comp = CompoundOwn::default();
    comp.insert("Int", 1);
    comp.insert("String", "2");
    comp.insert("ByteArray", [1i8, 2, 3]);
    nbt.insert("Compound", comp);
    let mut list = TypedListOwn::default();
    list.push(1);
    list.push(2);
    list.push(3);
    nbt.insert("List", list);
}
use na_nbt::{ValueRef, VisitRef, ListBase, ValueBase, CompoundRef, ListRef};

fn dump<'s>(value: &impl ValueRef<'s>, indent: usize) -> String {
    let pad = "  ".repeat(indent);
    value.visit(|v| match v {
        VisitRef::End(_) => format!("{pad}End"),
        VisitRef::Byte(v) => format!("{pad}Byte({v})"),
        VisitRef::Short(v) => format!("{pad}Short({v})"),
        VisitRef::Int(v) => format!("{pad}Int({v})"),
        VisitRef::Long(v) => format!("{pad}Long({v})"),
        VisitRef::Float(v) => format!("{pad}Float({v})"),
        VisitRef::Double(v) => format!("{pad}Double({v})"),
        VisitRef::ByteArray(v) => format!("{pad}ByteArray({} bytes)", v.len()),
        VisitRef::String(v) => format!("{pad}String({:?})", v.decode_lossy()),
        VisitRef::IntArray(v) => format!("{pad}IntArray({} ints)", v.len()),
        VisitRef::LongArray(v) => format!("{pad}LongArray({} longs)", v.len()),
        VisitRef::List(list) => {
            let mut out = format!("{pad}List[{}] {{\n", list.len());
            for item in list.iter() {
                out.push_str(&dump(&item, indent + 1));
                out.push('\n');
            }
            out.push_str(&format!("{pad}}}"));
            out
        }
        VisitRef::Compound(compound) => {
            let mut out = format!("{pad}Compound {{\n");
            for (key, val) in compound.iter() {
                let nested = dump(&val, indent + 1);
                out.push_str(&format!(
                    "{}  {:?}: {}\n",
                    pad,
                    key.decode_lossy(),
                    nested.trim_start()
                ));
            }
            out.push_str(&format!("{pad}}}"));
            out
        }
    })
}

§Serde support

na_nbt provides serde support. For serde-to-NBT type mapping, see tag_probe.

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Address {
    street: String,
    city: String,
}

fn an_address() -> na_nbt::Result<()> {
    let address = Address {
        street: "10 Downing Street".to_owned(),
        city: "London".to_owned(),
    };

    let j = na_nbt::to_vec_be(&address)?;
    let addr: Address = na_nbt::from_slice_be(&j)?;
    assert_eq!(addr, address);

    Ok(())
}

Re-exports§

pub use error::Error;
pub use error::Result;

Modules§

byte_array
Serializer and deserializer for NBT TAG_Byte_Array.
error
int_array
Serializer and deserializer for NBT TAG_Int_Array.
list
Serializer and deserializer for NBT TAG_List.
long_array
Serializer and deserializer for NBT TAG_Long_Array.
marker
Serialization markers for native NBT types.
tag
NBT tag type definitions.
tag_probe
Zero-cost tag type detection for serde values.

Structs§

CompoundOwn
Deserializer
NBT deserializer that reads from a byte slice.
F32
A 32-bit floating point number stored in a given byte order.
F64
A 64-bit floating point number stored in a given byte order.
I16
A 16-bit signed integer stored in a given byte order.
I32
A 32-bit signed integer stored in a given byte order.
I64
A 64-bit signed integer stored in a given byte order.
I128
A 128-bit signed integer stored in a given byte order.
ListOwn
MUTF8Str
A MUTF-8 (Modified UTF-8) encoded string slice.
Serializer
NBT serializer that writes to an internal byte vector.
TypedListOwn
U16
A 16-bit unsigned integer stored in a given byte order.
U32
A 32-bit unsigned integer stored in a given byte order.
U64
A 64-bit unsigned integer stored in a given byte order.
U128
A 128-bit unsigned integer stored in a given byte order.

Enums§

BigEndian
Big-endian byte order.
LittleEndian
Little-endian byte order.
MapMut
An owned variant for mapping mutable NBT values.
MapRef
An owned variant for mapping NBT values.
TagID
NBT tag type identifier.
ValueOwn
VisitMut
A unique mutable reference variant for visiting NBT values.
VisitMutShared
A shared mutable reference variant for visiting NBT values.
VisitRef
A reference variant for visiting NBT values.

Traits§

CompoundBase
Base trait for NBT compounds.
CompoundMut
Trait for mutable access to NBT compounds.
CompoundRef
Trait for read-only access to NBT compounds.
ListBase
Base trait for NBT lists.
ListMut
Trait for mutable access to NBT lists.
ListRef
Trait for read-only access to NBT lists.
TypedListBase
Base trait for typed NBT lists.
TypedListMut
Trait for mutable access to typed NBT lists.
TypedListRef
Trait for read-only access to typed NBT lists.
ValueBase
Base trait for all NBT values.
ValueMut
Trait for mutable access to NBT values.
ValueRef
Trait for read-only access to NBT values.
Writable
Trait for writing NBT values to bytes.

Functions§

from_reader
Deserializes a value from a reader in NBT format.
from_reader_be
Convenience function for reading from a reader with big-endian byte order.
from_reader_le
Convenience function for reading from a reader with little-endian byte order.
from_slice
Deserializes a value from a byte slice in NBT format.
from_slice_be
Convenience function for deserializing with big-endian byte order.
from_slice_le
Convenience function for deserializing with little-endian byte order.
read_borrowed
read_owned
read_owned_from_reader
read_shared
tag_of
Returns the NBT tag type that a value would serialize to.
to_vec
Serializes a value to a byte vector in NBT format.
to_vec_be
Convenience function for serializing with big-endian byte order.
to_vec_le
Convenience function for serializing with little-endian byte order.
to_writer
Serializes a value to a writer in NBT format.
to_writer_be
Convenience function for writing with big-endian byte order.
to_writer_le
Convenience function for writing with little-endian byte order.

Type Aliases§

BE
A type alias for BigEndian.
LE
A type alias for LittleEndian.
NativeEndian
The endianness used by this platform.