#nbt #minecraft #networking #crabcraft

crab_nbt

Up-to-date Rust crate for easy and intuitive working with NBT data

12 releases

0.2.4 Oct 12, 2024
0.2.3 Sep 21, 2024
0.1.3 Jul 31, 2024
0.1.1 Jun 25, 2024
0.0.3 Mar 24, 2024

#495 in Parser implementations

Download history 12/week @ 2024-07-04 115/week @ 2024-07-11 17/week @ 2024-07-18 81/week @ 2024-07-25 53/week @ 2024-08-01 12/week @ 2024-08-08 13/week @ 2024-08-15 171/week @ 2024-08-29 35/week @ 2024-09-05 191/week @ 2024-09-12 321/week @ 2024-09-19 95/week @ 2024-09-26 48/week @ 2024-10-03 184/week @ 2024-10-10 62/week @ 2024-10-17

400 downloads per month
Used in ussr-nbt

GPL-3.0-only

45KB
1K SLoC

🦀 CrabNBT

Up-to-date Rust crate for easy and intuitive working with NBT data.

Why not other libraries?

CrabNBT combines best features of existing NBT crates, to create perfect, easy to use solution.
Big thanks to simdnbt and fastnbt for ideas!

Features

✅ Support for serializing to/from Struct (serde)
Java string support
nbt! macro for easy creation
✅ Easy to use system of retrieving values from NBT
✅ Serialization support for individual tags
✅ Support for Network NBT

Installing

cargo add crab_nbt

Serializing

use crab_nbt::{nbt, Nbt, NbtCompound};

// Using NBT macro
let nbt = nbt!("root nbt_inner name", {
    "float": 1.0,
    "key": "value",
    "long_array": [L; 1, 2],
    "int_array": [Int; 1, 10, 25],
    "byte_array": [B; 0, 1, 0, 0, 1],
    "list": ["a", "b", "c"],
    "nbt_inner": {
        "key": "sub value"
    }
});

let nbt = Nbt::new(
    "root".to_owned(),
    NbtCompound::from_iter([
        ("float".to_owned(), 1.0.into()),
        ("key".to_owned(), "value".into()),
        ("nbt_inner".to_owned(), NbtCompound::from_iter([
            ("key".to_owned(), "sub value".into()),
        ]).into())
    ])
);

let network_bytes = nbt.write_unnamed();
let normal_bytes = nbt.write();

Deserializing

use bytes::Bytes;
use crab_nbt::{nbt, Nbt, NbtCompound};

fn example(bytes: &mut Bytes) {
    let nbt = Nbt::read(bytes).unwrap();
    let egg_name = nbt
        .get_compound("nbt_inner")
        .and_then(|compound| compound.get_compound("egg"))
        .and_then(|compound| compound.get_string("name"))
        .unwrap();
}

Serde

Requires serde feature.

use crab_nbt::serde::{arrays::IntArray, ser::to_bytes_unnamed, de::from_bytes_unnamed};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Test {
    number: i32,
    #[serde(with = "IntArray")]
    int_array: Vec<i32>,
}

fn cycle() {
    let test = Test {
        number: 5,
        int_array: vec![7, 8]
    };
    let mut bytes = to_bytes_unnamed(&test).unwrap();
    let recreated_struct: Test = from_bytes_unnamed(&mut bytes).unwrap();
    
    assert_eq!(test, recreated_struct);
}

Dependencies

~0.5–1MB
~22K SLoC