bookshelf/nbt/bin/
mod.rs

1pub mod ser;
2pub mod de;
3
4use crate::{
5    Endianness,
6    bin::{BinReader, BinWriter},
7    nbt::Result
8};
9
10use serde::Serialize;
11
12use std::io::{Read, Write};
13
14/// Takes in a [`Read`] implementation `R` and deserializes it as binary to a [`serde::Deserialize`] implementation `D`
15/// using endianness `E`.
16/// 
17/// Returns a tuple where the first element is the root name and the second element is the deserialized data.
18/// 
19/// # Examples
20/// ```
21/// use crate::{bin::BE, nbt::{Tag, from_reader}};
22/// use std::fs::read;
23/// 
24/// let input = read("bigtest.nbt")?;
25/// let (root_name, data) = from_reader::<BE, _, Tag>(&mut &input[..], true)?;
26/// ```
27pub fn from_reader<'de, E: Endianness, R: Read, D: serde::Deserialize<'de>>(
28    reader: R,
29    has_root_name: bool,
30) -> Result<(Option<String>, D)> {
31    let bin_reader = BinReader::<E, R>::new(reader);
32    let mut deserializer = de::RootDeserializer::from_reader(bin_reader, has_root_name);
33
34    let d = D::deserialize(&mut deserializer)?;
35
36    Ok((deserializer.root_name, d))
37}
38
39/// Takes in a [`Write`] implementation `W` and a [`serde::Serialize`] implementation `S` and writes it as binary in
40/// endianness `E`.
41pub fn to_writer<'a, E: Endianness, W: Write, S: Serialize + ?Sized>(writer: W, value: &S, root_name: Option<&'a str>) -> Result<()> {
42    Ok(value.serialize(&mut ser::PayloadSerializer {
43        writer: &mut BinWriter::<E, W>::new(writer),
44        state: match root_name {
45            Some(name) => ser::State::Named(name),
46            None => ser::State::NamelessRoot,
47        }
48    })?)
49}
50
51#[cfg(test)]
52mod test {
53    use super::*;
54    use crate::{BE, nbt::Tag};
55    use std::fs::read;
56
57    #[test]
58    fn serde() -> Result<()> {
59        let input = read("test/bigtest.nbt")?;
60
61        let (root_name, data) = from_reader::<BE, _, Tag>(&input[..], true)?;
62
63        assert_eq!(root_name, Some("Level".to_string()));
64
65        let mut output = vec![0; input.len()];
66
67        to_writer::<BE, _, Tag>(&mut output[..], &data, root_name.as_deref())?;
68
69        Ok(())
70    }
71
72    #[test]
73    fn invalid_tag_id() -> Result<()> {
74        // {a: [B;], b: {<invalid tag id>}}
75        let input: [u8; 16] = 
76        [0x0A, 0x00, 0x00, 0x07, 0x00, 0x01, 0x41, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x01, 0x42, 0x0F];
77        let result = from_reader::<BE, _, Tag>(&input[..], true);
78        println!("{}", result.unwrap_err());
79
80        Ok(())
81    }
82}