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