nbt/
lib.rs

1//! # Named Binary Tag (NBT)
2//! The The Named Binary Tag, is a structured binary format used by the game Minecraft for a variety
3//! of purposes such as, Player Data and World Saves as well as being used within the Minecraft Protocol.
4//!
5//! [NBT Specification](https://wiki.vg/NBT#Specification)
6//!
7//! ## This Crate
8//! This crate is __yet__ another implementation of the NBT format.
9//!
10//! ### Key features
11//! - Support for Serialisation and Deserialization with the [Serde](https://serde.rs) framework.
12//! - Ability to create partial or complete documents through the `Tag` and `Blob` objects.
13//! - Ability to read/write from a socket or buffer.
14//!
15//! ### Cargo Features
16//! - `with_serde`        (default) includes Serde serialisation and deserialization support.
17//! - `serde_boolean`     converts booleans to bytes during serialisation and deserialization.
18//! - `serde_unsigned`    converts unsigned to their signed counterparts during serialisation and deserialization.
19//! - `arrays`            utils for writing byte, int and long arrays. (dev branch)
20//! - `compression`       gzip and DEFLATE support. (dev branch)
21//!
22//! ### Operation
23//! This crate has two seperate operations that allow data to be mutated.
24//! 1. Read/Writing - `Tags/Blobs` `<--NBT-->` `Bytes/Buffer`
25//! 2. Encoding/Decoding - `Tags/Blobs` `<--Serde-->` `Structs`
26//!
27//! ## Quick Start
28//!
29//! #### Tags
30//! One way of creating partial NBT objects is with tags.
31//! ```
32//! use nbt::Tag;
33//!
34//! // An example of a TAG_Byte with value 42.
35//! let byte = Tag::Byte(42);
36//!
37//! // An example of a TAG_String with value "Hello!"
38//! let string = Tag::String("Hello!".to_string());
39//!
40//! // An example of TAG_List containing bytes, with values of [1,2,3]
41//! let list = Tag::List(vec![Tag::Byte(1), Tag::Byte(2), Tag::Byte(3)]);
42//!
43//! // An example of a compound
44//! use std::collections::HashMap;
45//! let mut map = HashMap::<String, Tag>::new();
46//! map.insert("age".to_string(), Tag::Byte(18));
47//! map.insert("id".to_string(), Tag::Int(69420));
48//! let compound = Tag::Compound(map);
49//! ```
50//! #### Blobs
51//! Blobs allow for you to create full NBT objects/documents.
52//! ```
53//! use nbt::{Blob, Tag};
54//!
55//! // Creating a blob
56//! let mut blob = Blob::new();
57//!
58//! // Inserting a tag
59//! blob.insert("age", Tag::Byte(18));
60//!
61//! // Using the ToTag trait to insert a tag.
62//! blob.insert("id", 69420_i32);
63//! ```
64//! Blobs reprsent the root compound, and hence can be named.
65//!
66//! When a name is not specifed it defaults to `""`
67//! ```
68//! use nbt::{Blob};
69//!
70//! // Creating a blob with a name
71//! let mut blob = Blob::create("user");
72//! blob.insert("name", "pokechu22");
73//! ```
74//!
75//! #### Encoding / Writing
76//! You can encode a partial or full NBT object using the `NBTWrite` trait.
77//! ```
78//! use nbt::{Tag, NBTWrite};
79//! let tag = Tag::Float(69.420);
80//!
81//! // Writing to a buffer
82//! let mut buffer = Vec::new();
83//! tag.write(&mut buffer).unwrap();
84//!
85//! // Outputting to a Vec.
86//! let bytes = tag.bytes().unwrap();
87//!
88//! println!("{:?}", bytes);
89//! ```
90//!
91//! #### Decoding / Reading
92//! ```
93//! use nbt::{Tag, NBTWrite, NBTRead};
94//! let data = /* vec![...] */
95//! # vec![10, 0, 11, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 8, 0, 4, 110, 97, 109, 101, 0, 9, 66, 97, 110, 97, 110, 114, 97, 109, 97, 0];
96//!
97//! // Reading from a buffer
98//! use std::io::Cursor;
99//! let mut cursor = Cursor::new(data.clone());
100//! let one = Tag::read(&mut cursor).unwrap();
101//! // Also works for: Blob::read(...)
102//!
103//! // Reading from vec
104//! let two = Tag::from_bytes(data);
105//! // Also works for: Blob::from_bytes(...)
106//! ```
107//!
108//! ### Serde
109//! This library has full serde serialisation and deserialization support for all types in the
110//! [serde data model](https://serde.rs/data-model.html) except for u8 (byte)arrays.
111//!
112//! Serde support requires the `with_serde` cargo feature, which is enabled by default.
113//!
114//! #### Encoding
115//! Here is an basic example for encoding between a struct and bytes
116//! ```rust
117//! use serde::Serialize;
118//! use nbt::{encode, NBTWrite};
119//!
120//! // Define a Serializable struct
121//! #[derive(Serialize)]
122//! pub struct HelloWorld {
123//!     name: String
124//! }
125//!
126//! // Instantiate
127//! let hello = HelloWorld {
128//!     name: "Dinnerbone".to_string()
129//! };
130//!
131//! // Encode/Serialise the struct into a blob.
132//! let blob = encode(&hello).unwrap();
133//!
134//! // get the bytes from the blob.
135//! let bytes = blob.bytes().unwrap();
136//!
137//! 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])
138//! ```
139//!
140//! #### Decoding
141//! Here is the reverse operation for the above example
142//! ```
143//! use serde::Deserialize;
144//! use nbt::{Blob, NBTRead, decode};
145//!
146//! // Define a Deserialisable struct
147//! #[derive(Deserialize, PartialEq, Debug)]
148//! pub struct HelloWorld {
149//!     name: String
150//! }
151//!
152//! // Bytes
153//! 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];
154//!
155//! // Create a blob from bytes
156//! let blob = Blob::from_bytes(bytes).unwrap();
157//!
158//! // Deserialize the blob into the struct
159//! let hello = decode::<HelloWorld>(blob).unwrap();
160//!
161//! assert_eq!(hello, HelloWorld {
162//!     name: "Dinnerbone".to_string()
163//! });
164//! ```
165//!
166//! #### Serde Functions
167//! - `BLOB --> SERDE` [`decode(...)`](crate::decode())
168//! - `BLOB <-- SERDE` [`encode(...)`](crate::encode())
169//! - `TAG --> SERDE` [`decode_tag(...)`](crate::decode_tag)
170//! - `TAG <-- SERDE` [`encode_tag(...)`](crate::encode_tag)
171//! - `BLOB --> SERDE + NAME` [`decode_named(...)`](crate::decode_named)
172//! - `BLOB <-- SERDE + NAME` [`encode_named(...)`](crate::encode_named)
173
174pub(crate) mod tags;
175pub(crate) mod error;
176pub(crate) mod blob;
177pub(crate) mod encode;
178pub(crate) mod decode;
179pub(crate) mod front;
180pub(crate) mod util;
181
182pub use util::{FromTag, ToTag};
183pub use front::{NBTWrite, NBTRead};
184pub use blob::Blob;
185pub use tags::{TagIdent, Tag};
186
187#[cfg(test)]
188pub mod tests;
189
190#[cfg(feature="with_serde")]
191mod ser;
192#[cfg(feature="with_serde")]
193mod de;
194
195#[cfg(feature="with_serde")]
196pub use front::{encode, encode_named, encode_tag, decode, decode_named, decode_tag};