use std::path::Path; use anyhow::Context; use memofs::Vfs; use crate::snapshot::{InstanceContext, InstanceMetadata, InstanceSnapshot}; use super::util::PathExt; pub fn snapshot_rbxmx( context: &InstanceContext, vfs: &Vfs, path: &Path, ) -> anyhow::Result> { let name = path.file_name_trim_end(".rbxmx")?; 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(name) .metadata( InstanceMetadata::new() .instigating_source(path) .relevant_paths(vec![path.to_path_buf()]) .context(context), ); Ok(Some(snapshot)) } else { anyhow::bail!( "Rojo currently only supports model files with one top-level instance.\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#" THIS NAME IS IGNORED "#, ), ) .unwrap(); let mut vfs = Vfs::new(imfs); let instance_snapshot = snapshot_rbxmx( &InstanceContext::default(), &mut vfs, Path::new("/foo.rbxmx"), ) .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()); } }