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}