[][src]Crate fastnbt

fastnbt aims for fast parsing of NBT data from Minecraft: Java Edition. This format is used by the game to store various things, such as the world data and player inventories.

For documentation and examples of serde deserialization, see the de module.

Both this and related crates are under one fastnbt Github repository

fastnbt = "0.14"

Quick example

This example demonstrates printing out a players inventory and ender chest contents from the player dat files found in worlds. We leverage serde's renaming attribute to have rustfmt conformant field names, use lifetimes to save on some string allocations, and use the Value type to deserialize a field we don't specify the exact structure of.

 use fastnbt::error::Result;
 use fastnbt::{de::from_bytes, Value};
 use flate2::read::GzDecoder;
 use serde::Deserialize;
 use std::io::Read;

 #[derive(Deserialize, Debug)]
 #[serde(rename_all = "PascalCase")]
 struct PlayerDat<'a> {
     data_version: i32,

     inventory: Vec<InventorySlot<'a>>,
     ender_items: Vec<InventorySlot<'a>>,

 #[derive(Deserialize, Debug)]
 struct InventorySlot<'a> {
     id: &'a str,        // We avoid allocating a string here.
     tag: Option<Value>, // Also get the less structured properties of the object.

     // We need to rename fields a lot.
     #[serde(rename = "Count")]
     count: i8,

 fn main() {
     let args: Vec<_> = std::env::args().skip(1).collect();
     let file = std::fs::File::open(args[0].clone()).unwrap();

     // Player dat files are compressed with GZip.
     let mut decoder = GzDecoder::new(file);
     let mut data = vec![];
     decoder.read_to_end(&mut data).unwrap();

     let player: Result<PlayerDat> = from_bytes(data.as_slice());

     println!("{:#?}", player);

Read based parser

A lower level parser also exists in the stream module that only requires the Read trait on the input. This parser however doesn't support deserializing to Rust objects directly.



This module contains a serde deserializer. It can do most of the things you would expect of a typical serde deserializer, such as deserializing into:


Contains the Error and Result type used by the deserializer.


Allows streaming of NBT data without prior knowledge of the structure.



An NBT tag. This does not carry the value or the name of the data.


Value is a complete NBT value. It owns it's data. The Byte, Short, Int and Long NBT types are all deserialized into i64. Compounds and Lists are resursively deserialized.