1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*!
Implementation of Roblox's binary model (rbxm) and place (rbxl) file formats.

# Examples

## Read a model file

To read a model or place file using rbx_binary's default settings, use
[`from_reader`]. The [`Deserializer`] API exposes additional configuration
options.

```no_run
use std::fs::File;
use std::io::BufReader;

// Using buffered I/O is recommended with rbx_binary
let input = BufReader::new(File::open("MyModel.rbxm")?);

let dom = rbx_binary::from_reader(input)?;

// rbx_binary always returns a DOM with a DataModel at the top level.
// To get to the instances from our file, we need to go one level deeper.

println!("Root instances in file:");
for &referent in dom.root().children() {
    let instance = dom.get_by_ref(referent).unwrap();
    println!("- {}", instance.name);
}

# Ok::<(), Box<dyn std::error::Error>>(())
```

## Write a model file

To write a model or place file using rbx_binary's default settings, use
[`to_writer`]. The [`Serializer`] API exposes additional configuration options.

```no_run
use std::fs::File;
use std::io::BufWriter;

use rbx_dom_weak::{InstanceBuilder, WeakDom};

let dom = WeakDom::new(InstanceBuilder::new("Folder"));

// Using buffered I/O is recommended with rbx_binary
let output = BufWriter::new(File::create("PlainFolder.rbxm")?);
rbx_binary::to_writer(output, &dom, &[dom.root_ref()])?;

# Ok::<(), Box<dyn std::error::Error>>(())
```
*/

#![deny(missing_docs)]

mod chunk;
mod core;
mod deserializer;
mod serializer;
mod types;

#[cfg(any(test, feature = "unstable_text_format"))]
mod text_deserializer;

#[cfg(test)]
mod tests;

use std::io::{Read, Write};

use rbx_dom_weak::{types::Ref, WeakDom};

/// An unstable textual format that can be used to debug binary models.
#[cfg(feature = "unstable_text_format")]
pub mod text_format {
    pub use crate::text_deserializer::*;
}

pub use crate::{
    deserializer::{Deserializer, Error as DecodeError},
    serializer::{Error as EncodeError, Serializer},
};

/// Deserialize a Roblox binary model or place from a stream.
pub fn from_reader<R: Read>(reader: R) -> Result<WeakDom, DecodeError> {
    Deserializer::new().deserialize(reader)
}

/// Serializes a subset of the given DOM to a binary format model or place,
/// writing to something that implements the `std::io::Write` trait.
pub fn to_writer<W: Write>(writer: W, dom: &WeakDom, refs: &[Ref]) -> Result<(), EncodeError> {
    Serializer::new().serialize(writer, dom, refs)
}