Expand description
§Named Binary Tag (NBT)
The The Named Binary Tag, is a structured binary format used by the game Minecraft for a variety of purposes such as, Player Data and World Saves as well as being used within the Minecraft Protocol.
§This Crate
This crate is yet another implementation of the NBT format.
§Key features
- Support for Serialisation and Deserialization with the Serde framework.
- Ability to create partial or complete documents through the
Tag
andBlob
objects. - Ability to read/write from a socket or buffer.
§Cargo Features
with_serde
(default) includes Serde serialisation and deserialization support.serde_boolean
converts booleans to bytes during serialisation and deserialization.serde_unsigned
converts unsigned to their signed counterparts during serialisation and deserialization.arrays
utils for writing byte, int and long arrays. (dev branch)compression
gzip and DEFLATE support. (dev branch)
§Operation
This crate has two seperate operations that allow data to be mutated.
- Read/Writing -
Tags/Blobs
<--NBT-->
Bytes/Buffer
- Encoding/Decoding -
Tags/Blobs
<--Serde-->
Structs
§Quick Start
§Tags
One way of creating partial NBT objects is with tags.
use nbt::Tag;
// An example of a TAG_Byte with value 42.
let byte = Tag::Byte(42);
// An example of a TAG_String with value "Hello!"
let string = Tag::String("Hello!".to_string());
// An example of TAG_List containing bytes, with values of [1,2,3]
let list = Tag::List(vec![Tag::Byte(1), Tag::Byte(2), Tag::Byte(3)]);
// An example of a compound
use std::collections::HashMap;
let mut map = HashMap::<String, Tag>::new();
map.insert("age".to_string(), Tag::Byte(18));
map.insert("id".to_string(), Tag::Int(69420));
let compound = Tag::Compound(map);
§Blobs
Blobs allow for you to create full NBT objects/documents.
use nbt::{Blob, Tag};
// Creating a blob
let mut blob = Blob::new();
// Inserting a tag
blob.insert("age", Tag::Byte(18));
// Using the ToTag trait to insert a tag.
blob.insert("id", 69420_i32);
Blobs reprsent the root compound, and hence can be named.
When a name is not specifed it defaults to ""
use nbt::{Blob};
// Creating a blob with a name
let mut blob = Blob::create("user");
blob.insert("name", "pokechu22");
§Encoding / Writing
You can encode a partial or full NBT object using the NBTWrite
trait.
use nbt::{Tag, NBTWrite};
let tag = Tag::Float(69.420);
// Writing to a buffer
let mut buffer = Vec::new();
tag.write(&mut buffer).unwrap();
// Outputting to a Vec.
let bytes = tag.bytes().unwrap();
println!("{:?}", bytes);
§Decoding / Reading
use nbt::{Tag, NBTWrite, NBTRead};
let data = /* vec![...] */
// Reading from a buffer
use std::io::Cursor;
let mut cursor = Cursor::new(data.clone());
let one = Tag::read(&mut cursor).unwrap();
// Also works for: Blob::read(...)
// Reading from vec
let two = Tag::from_bytes(data);
// Also works for: Blob::from_bytes(...)
§Serde
This library has full serde serialisation and deserialization support for all types in the serde data model except for u8 (byte)arrays.
Serde support requires the with_serde
cargo feature, which is enabled by default.
§Encoding
Here is an basic example for encoding between a struct and bytes
use serde::Serialize;
use nbt::{encode, NBTWrite};
// Define a Serializable struct
#[derive(Serialize)]
pub struct HelloWorld {
name: String
}
// Instantiate
let hello = HelloWorld {
name: "Dinnerbone".to_string()
};
// Encode/Serialise the struct into a blob.
let blob = encode(&hello).unwrap();
// get the bytes from the blob.
let bytes = blob.bytes().unwrap();
assert_eq!(bytes, vec![10, 0, 0, 8, 0, 4, 110, 97, 109, 101, 0, 10, 68, 105, 110, 110, 101, 114, 98, 111, 110, 101, 0])
§Decoding
Here is the reverse operation for the above example
use serde::Deserialize;
use nbt::{Blob, NBTRead, decode};
// Define a Deserialisable struct
#[derive(Deserialize, PartialEq, Debug)]
pub struct HelloWorld {
name: String
}
// Bytes
let bytes = vec![10, 0, 0, 8, 0, 4, 110, 97, 109, 101, 0, 10, 68, 105, 110, 110, 101, 114, 98, 111, 110, 101, 0];
// Create a blob from bytes
let blob = Blob::from_bytes(bytes).unwrap();
// Deserialize the blob into the struct
let hello = decode::<HelloWorld>(blob).unwrap();
assert_eq!(hello, HelloWorld {
name: "Dinnerbone".to_string()
});
§Serde Functions
BLOB --> SERDE
decode(...)
BLOB <-- SERDE
encode(...)
TAG --> SERDE
decode_tag(...)
TAG <-- SERDE
encode_tag(...)
BLOB --> SERDE + NAME
decode_named(...)
BLOB <-- SERDE + NAME
encode_named(...)
Structs§
- Blob
- A NBT Document containing an implicit compound and root name.
Enums§
- Tag
- A NBT Tag, representing the 13 datatypes supported by the format.
- TagIdent
- The numerical representation of Tag types.
Traits§
- FromTag
- A trait to convert NBT tags into rust types.
- NBTRead
- A trait supporting decoding of bytes into NBT/Tags.
- NBTWrite
- A trait supporting encoding of NBT Tags/Blobs into bytes.
- ToTag
- A trait to convert rust types into their respective NBT Tag.
Functions§
- decode
- Decode a NBT Blob into a Serde deserializable value.
- decode_
named - Decode a NBT Blob into a Serde deserializable value and the given root name.
- decode_
tag - Decode a NBT Tag into a Serde deserializable value.
- encode
- Encode a Serde serializable value into a NBT Blob with a empty root name.
- encode_
named - Encode a Serde serializable value into a NBT Blob with a given root name.
- encode_
tag - Encode a Serde serializable value into a NBT Tag.