Files
rojo/src/snapshot_middleware/rbxmx.rs
Lucien Greathouse 59ef5f05ea Upgrade to rbx_dom_weak 2.0 (#377)
* Mostly mechanical port bits

* Almost there

* It builds again!

* Turn on all the code again

* Tests compiling but not passing

* Stub work for value resolution

* Implement resolution minus enums and derived properties

* Implement property descriptor resolution

* Update referent snapshots

* Update unions test project

Using a place file instead of a model yields better
error messages in Roblox Studio.

* Add easy shortcut to testing with local rbx-dom

* Update rbx-dom

* Add enum resolution

* Update init.meta.json to use UnresolvedValue

* Expand value resolution support, add test

* Filter SharedString values from web API

* Add 'property' builder method to InstanceSnapshot

* Change InstanceSnapshot/InstanceBuilder boundary

* Fix remove_file crash

* rustfmt

* Update to latest rbx_dom_lua

* Update dependencies, including rbx_dom_weak

* Update to latest rbx-dom

* Update dependencies

* Update rbx-dom, fixing more bugs

* Remove experimental warning on binary place builds

* Remove unused imports
2021-02-18 20:56:09 -05:00

87 lines
2.4 KiB
Rust

use std::path::Path;
use anyhow::Context;
use memofs::Vfs;
use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot};
use super::middleware::SnapshotInstanceResult;
pub fn snapshot_rbxmx(
context: &InstanceContext,
vfs: &Vfs,
path: &Path,
instance_name: &str,
) -> SnapshotInstanceResult {
let options = rbx_xml::DecodeOptions::new()
.property_behavior(rbx_xml::DecodePropertyBehavior::ReadUnknown);
let temp_tree = rbx_xml::from_reader(vfs.read(path)?.as_slice(), options)
.with_context(|| format!("Malformed rbxm file: {}", path.display()))?;
let root_instance = temp_tree.root();
let children = root_instance.children();
if children.len() == 1 {
let snapshot = InstanceSnapshot::from_tree(&temp_tree, children[0])
.name(instance_name)
.metadata(
InstanceMetadata::new()
.instigating_source(path)
.relevant_paths(vec![path.to_path_buf()])
.context(context),
);
Ok(Some(snapshot))
} else {
anyhow::bail!(
"Rojo doesn't have support for model files with zero or more than one top-level instances yet.\n\n \
Check the model file at path {}",
path.display()
);
}
}
#[cfg(test)]
mod test {
use super::*;
use memofs::{InMemoryFs, VfsSnapshot};
#[test]
fn plain_folder() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo.rbxmx",
VfsSnapshot::file(
r#"
<roblox version="4">
<Item class="Folder" referent="0">
<Properties>
<string name="Name">THIS NAME IS IGNORED</string>
</Properties>
</Item>
</roblox>
"#,
),
)
.unwrap();
let mut vfs = Vfs::new(imfs);
let instance_snapshot = snapshot_rbxmx(
&InstanceContext::default(),
&mut vfs,
Path::new("/foo.rbxmx"),
"foo",
)
.unwrap()
.unwrap();
assert_eq!(instance_snapshot.name, "foo");
assert_eq!(instance_snapshot.class_name, "Folder");
assert_eq!(instance_snapshot.properties, Default::default());
assert_eq!(instance_snapshot.children, Vec::new());
}
}