Macro quartz_nbt::compound

source ·
compound!() { /* proc-macro */ }
Expand description

A utility macro for constructing NbtCompounds.

With exceptions for arrays and compounds, all keys and values must be well-formed rust expressions. The benefit of this is that local variables can be included in the generated compound. If a local variable is of the type Vec<T>, then the generated code will try to convert the variable to an NbtTag, which will fail unless Vec<T> maps onto a specialized array type. If it is desireable for the variable to serialize as a tag list, then it should be wrapped in NbtList::from.

let product = 87235i32 * 932i32;
let byte_array = vec![0i8, 2, 4];
let tag_list = byte_array.clone();

let compound = compound! {
    "product": product,
    "foo": "bar",
    "byte_array": byte_array,
    "tag_list": NbtList::from(tag_list)
};

let mut manual_compound = NbtCompound::new();
manual_compound.insert("product", 81303020i32);
manual_compound.insert("foo", "bar");
manual_compound.insert("byte_array", vec![0i8, 2, 4]);
manual_compound.insert("tag_list", NbtList::from(vec![0i8, 2, 4]));

assert_eq!(compound, manual_compound);

Similar to SNBT, constant specialized array types can be opted-into with a type specifier:

let compound = compound! {
    "byte_array": [B; 1, 2, 3],
    "int_array": [I; 4, 5, 6],
    "long_array": [L; 7, 8, 9],
    "tag_array": [10, 11, 12]
};

assert!(matches!(compound.get::<_, &NbtTag>("byte_array"), Ok(NbtTag::ByteArray(_))));
assert!(matches!(compound.get::<_, &NbtTag>("int_array"), Ok(NbtTag::IntArray(_))));
assert!(matches!(compound.get::<_, &NbtTag>("long_array"), Ok(NbtTag::LongArray(_))));
assert!(matches!(compound.get::<_, &NbtTag>("tag_array"), Ok(NbtTag::List(_))));

assert_eq!(
    compound.get::<_, &[i64]>("long_array")
        .unwrap()
        .iter()
        .copied()
        .sum::<i64>(),
    24
);

Just like in JSON or SNBT, compounds are enclosed by braces:

let compound = compound! {
    "nested": {
        "a": [I;],
        "b": []
    }
};

let mut outer = NbtCompound::new();
let mut nested = NbtCompound::new();
nested.insert("a", Vec::<i32>::new());
nested.insert("b", NbtList::new());
outer.insert("nested", nested);

assert_eq!(compound, outer);