nbt/
front.rs

1use std::io::{Write, Read, Cursor};
2use crate::error::{NBTResult, NBTError};
3use crate::tags::Tag;
4use crate::encode::{write_tag, write_root};
5use crate::blob::Blob;
6use crate::decode::{read_tag, read_ident, read_root};
7use serde::Serialize;
8use crate::ser::NBTSerializer;
9use crate::TagIdent;
10use serde::de::DeserializeOwned;
11use crate::de::NBTDeserializer;
12
13/// A trait supporting encoding of NBT Tags/Blobs into bytes.
14pub trait NBTWrite {
15    fn write<W: Write>(&self, writer: &mut W) -> NBTResult<()>;
16
17    fn bytes(&self) -> NBTResult<Vec<u8>> {
18        let mut buffer = Vec::new();
19        self.write(&mut buffer)?;
20        Ok(buffer)
21    }
22}
23
24impl NBTWrite for Tag {
25    fn write<W: Write>(&self, writer: &mut W) -> NBTResult<()> {
26        write_tag(writer, &self)
27    }
28}
29impl NBTWrite for Blob {
30    fn write<W: Write>(&self, writer: &mut W) -> NBTResult<()> {
31        write_root(writer, &self.root, &self.elements)
32    }
33}
34
35/// A trait supporting decoding of bytes into NBT/Tags.
36///
37/// This trait provides two functions:
38/// - `read` for reading from a readable source or buffer
39/// - `from_bytes` for reading from a array of bytes
40///
41///
42pub trait NBTRead: Sized {
43    /// Function for reading from a buffer.
44    fn read<R: Read>(reader: &mut R) -> NBTResult<Self>;
45
46    /// Function for reading from a byte array.
47    fn from_bytes<B: AsRef<[u8]>>(data: B) -> NBTResult<Self> {
48        Self::read(&mut Cursor::new(data.as_ref().to_vec()))
49    }
50}
51
52impl NBTRead for Tag {
53    fn read<R: Read>(reader: &mut R) -> NBTResult<Self> {
54        let ident = read_ident(reader)?;
55        read_tag(reader, &ident)
56    }
57}
58impl NBTRead for Blob {
59    fn read<R: Read>(reader: &mut R) -> NBTResult<Self> {
60        let (name, elements) = read_root(reader)?;
61        Ok(Self { root: name, elements })
62    }
63}
64
65#[cfg(feature="with_serde")]
66/// Encode a Serde serializable value into a NBT Tag.
67///
68/// ### Example
69/// ```
70/// use nbt::{encode_tag, Tag};
71///
72/// let list: Vec<i8> = vec![127, 42, 10];
73/// let tag = encode_tag(&list).unwrap().unwrap();
74///
75/// # assert_eq!(tag, Tag::List(vec![Tag::Byte(127), Tag::Byte(42), Tag::Byte(10)]));
76/// ```
77pub fn encode_tag<T: Serialize>(o: &T) -> NBTResult<Option<Tag>> {
78    o.serialize(NBTSerializer)
79}
80
81/// Encode a Serde serializable value into a NBT Blob with a given root name.
82///
83/// ### Example
84/// ```
85/// use nbt::{encode_tag, encode_named, Tag};
86/// use std::collections::HashMap;
87/// use serde::Serialize;
88///
89/// // Define a Serializable Struct
90/// #[derive(Serialize)]
91/// pub struct Example {
92///     name: String,
93/// }
94///
95/// // Create a instance
96/// let example = Example {
97///     name: "Bananrama".to_string(),
98/// };
99/// // Encode a NBT blob with name "hello_world"
100/// let tag = encode_named(&example, "hello_world").unwrap();
101///
102/// # let mut test = HashMap::new();
103/// # test.insert("name".to_string(), Tag::String("Bananrama".to_string()));
104/// # assert_eq!(tag.compound(), Tag::Compound(test));
105/// ```
106///
107#[cfg(feature="with_serde")]
108pub fn encode_named<T: Serialize>(o: &T, name: &str) -> NBTResult<Blob> {
109    match encode_tag(o)? {
110        Some(tag) => if let Tag::Compound(map) = tag {
111            Ok(Blob { elements: map, root: name.to_string() })
112        } else {
113            Err(NBTError::InvalidImplicit { found: tag.ident() })
114        },
115        // Not sure about this
116        None => Err(NBTError::InvalidImplicit { found: TagIdent::TAG_End })
117    }
118}
119
120#[cfg(feature="with_serde")]
121/// Encode a Serde serializable value into a NBT Blob with a empty root name.
122///
123/// Encode a Serde serializable value into a NBT Blob with a given root name.
124/// Encode a Serde serializable value into a NBT Blob with a given root name.
125///
126/// ### Example
127/// ```
128/// use nbt::{encode_tag, encode, Tag};
129/// use std::collections::HashMap;
130/// use serde::Serialize;
131///
132/// // Define a Serializable Struct
133/// #[derive(Serialize)]
134/// pub struct Example {
135///     foo: String,
136///     bar: i8,
137///     baz: i16
138/// }
139///
140/// // Create a instance
141/// let example = Example {
142///     foo: "Hello World!".to_string(),
143///     bar: 42,
144///     baz: 25565
145/// };
146/// // Encode a NBT blob with name "example"
147/// let tag = encode(&example).unwrap();
148///
149/// # let mut test = HashMap::new();
150/// # test.insert("foo".to_string(), Tag::String("Hello World!".to_string()));
151/// # test.insert("bar".to_string(), Tag::Byte(42));
152/// # test.insert("baz".to_string(), Tag::Short(25565));
153/// # assert_eq!(tag.compound(), Tag::Compound(test));
154/// ```
155///
156pub fn encode<T: Serialize>(o: &T) -> NBTResult<Blob> {
157    encode_named(o, "")
158}
159
160#[cfg(feature="with_serde")]
161/// Decode a NBT Tag into a Serde deserializable value.
162///
163/// ### Example
164/// ```
165/// use nbt::{Tag, decode_tag};
166///
167/// // Create a Byte List.
168/// let tag = Tag::List(vec![Tag::Byte(127), Tag::Byte(42)]);
169///
170/// // Decode the tag into a vec.
171/// let list: Vec<i8> = decode_tag(tag).unwrap();
172///
173/// assert_eq!(list, vec![127, 42]);
174/// ```
175pub fn decode_tag<T: DeserializeOwned>(tag: Tag) -> NBTResult<T> {
176    T::deserialize(NBTDeserializer::some(tag))
177}
178
179
180#[cfg(feature="with_serde")]
181/// Decode a NBT Blob into a Serde deserializable value.
182///
183/// ### Example
184/// ```
185/// use nbt::{Tag, decode, Blob};
186/// use serde::Deserialize;
187///
188/// // Create Deserializable struct
189/// #[derive(Deserialize, PartialEq, Debug)]
190/// pub struct Example {
191///     foo: String
192/// }
193///
194/// // Create a Blob
195/// let mut blob = Blob::new();
196/// blob.insert("foo", "bar");
197///
198/// // Decode the data from blob
199/// let data: Example = decode(blob).unwrap();
200///
201/// assert_eq!(data, Example { foo: "bar".to_string() });
202/// ```
203pub fn decode<T: DeserializeOwned>(tag: Blob) -> NBTResult<T> {
204    T::deserialize(NBTDeserializer::some(Tag::Compound(tag.elements)))
205}
206
207#[cfg(feature="with_serde")]
208/// Decode a NBT Blob into a Serde deserializable value and the given root name.
209///
210/// ### Example
211/// ```
212/// use nbt::{Tag, Blob, decode_named};
213/// use serde::Deserialize;
214///
215/// // Create Deserializable struct
216/// #[derive(Deserialize, PartialEq, Debug)]
217/// pub struct Example {
218///     foo: String
219/// }
220///
221/// // Create a Blob
222/// let mut blob = Blob::create("baz");
223/// blob.insert("foo", "bar");
224///
225/// // Decode the root name and data from blob
226/// let (root, data): (String, Example) = decode_named(blob).unwrap();
227///
228/// assert_eq!(data, Example { foo: "bar".to_string() });
229/// assert_eq!(root, "baz".to_string());
230/// ```
231pub fn decode_named<T: DeserializeOwned>(tag: Blob) -> NBTResult<(String, T)> {
232    Ok((tag.root.clone(), T::deserialize(NBTDeserializer::some(Tag::Compound(tag.elements)))?))
233}
234