nbt/blob.rs
1use crate::tags::Tag;
2use std::ops::Deref;
3use std::collections::HashMap;
4use crate::util::{ToTag, FromTag};
5
6#[derive(Debug)]
7/// A NBT Document containing an implicit compound and root name.
8///
9/// ## Example
10/// ```
11/// # use nbt::{Blob, NBTWrite, NBTRead};
12///
13/// // Creation
14/// let mut blob = Blob::create("hello world");
15/// blob.insert("name", "Bananrama");
16///
17/// // Encoding
18/// let bytes = blob.bytes().unwrap();
19///
20/// // Decoding
21/// let decoded = Blob::from_bytes(bytes).unwrap();
22///
23/// // Retrieval
24/// assert_eq!(decoded.get::<String>("name").unwrap(), &("Bananrama".to_string()))
25/// ```
26///
27pub struct Blob {
28 /// Name of the root compound
29 pub root: String,
30 /// Elements of the root compound
31 pub elements: HashMap<String, Tag>
32}
33
34impl Blob {
35 /// Create a new `Blob` with a given root compound name.
36 pub fn create(root: &str) -> Blob {
37 Blob { root: root.to_string() , elements: HashMap::new() }
38 }
39
40 /// Create a new `Blob` with a empty root name.
41 pub fn new() -> Blob {
42 Blob { root: String::new() , elements: HashMap::new() }
43 }
44
45 /// Insert a element into the root compound.
46 ///
47 /// The payload element takes a `Tag` or any type that implements `ToTag`
48 /// ```
49 /// # use nbt::{Blob, Tag};
50 /// # let mut blob = Blob::new();
51 /// blob.insert("name", "Hello World");
52 /// blob.insert("name", Tag::Byte(127));
53 /// ```
54 pub fn insert<P: ToTag>(&mut self, name: &str, payload: P) -> Option<Tag> {
55 self.elements.insert(name.to_string(), payload.into_tag())
56 }
57
58 /// Get a element from the root compound, with a given type.
59 ///
60 /// Uses the `FromTag` trait to convert a tag into a desired type.
61 /// ```
62 /// # use nbt::Blob;
63 /// # let mut blob = Blob::new();
64 /// # blob.insert("name", "Hello World");
65 /// let name = blob.get::<String>("name"); // Some("Hello World")
66 /// let none = blob.get::<i8>("name"); // None
67 /// # assert_eq!(name.unwrap(), &("Hello World".to_string()));
68 /// # assert_eq!(none, None)
69 /// ```
70 pub fn get<T: FromTag>(&self, name: &str) -> Option<&T> where Self: Sized {
71 T::from_borrowed_tag(self.elements.get(&name.to_string())?.clone())
72 }
73
74 /// Get the NBT blob as a compound tag.
75 pub fn compound(self) -> Tag {
76 Tag::Compound(self.elements)
77 }
78}
79
80impl Deref for Blob {
81 type Target = HashMap<String, Tag>;
82
83 fn deref(&self) -> &Self::Target {
84 &self.elements
85 }
86}