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
This commit is contained in:
Lucien Greathouse
2021-02-18 20:56:09 -05:00
committed by GitHub
parent b84aab0960
commit 59ef5f05ea
63 changed files with 45602 additions and 21004 deletions

View File

@@ -1,11 +1,9 @@
use std::{borrow::Cow, collections::HashMap, path::Path};
use std::{borrow::Cow, collections::HashMap, path::PathBuf};
use anyhow::Context;
use rbx_dom_weak::UnresolvedRbxValue;
use rbx_reflection::try_resolve_value;
use anyhow::{format_err, Context};
use serde::{Deserialize, Serialize};
use crate::snapshot::InstanceSnapshot;
use crate::{resolution::UnresolvedValue, snapshot::InstanceSnapshot};
/// Represents metadata in a sibling file with the same basename.
///
@@ -18,17 +16,23 @@ pub struct AdjacentMetadata {
pub ignore_unknown_instances: Option<bool>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub properties: HashMap<String, UnresolvedRbxValue>,
pub properties: HashMap<String, UnresolvedValue>,
#[serde(skip)]
pub path: PathBuf,
}
impl AdjacentMetadata {
pub fn from_slice(slice: &[u8], path: &Path) -> anyhow::Result<Self> {
serde_json::from_slice(slice).with_context(|| {
pub fn from_slice(slice: &[u8], path: PathBuf) -> anyhow::Result<Self> {
let mut meta: Self = serde_json::from_slice(slice).with_context(|| {
format!(
"File contained malformed .meta.json data: {}",
path.display()
)
})
})?;
meta.path = path;
Ok(meta)
}
pub fn apply_ignore_unknown_instances(&mut self, snapshot: &mut InstanceSnapshot) {
@@ -37,23 +41,24 @@ impl AdjacentMetadata {
}
}
pub fn apply_properties(&mut self, snapshot: &mut InstanceSnapshot) {
let class_name = &snapshot.class_name;
pub fn apply_properties(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
let path = &self.path;
let source_properties = self.properties.drain().map(|(key, value)| {
try_resolve_value(class_name, &key, &value)
.map(|resolved| (key, resolved))
.expect("TODO: Handle rbx_reflection errors")
});
for (key, unresolved) in self.properties.drain() {
let value = unresolved
.resolve(&snapshot.class_name, &key)
.with_context(|| format!("error applying meta file {}", path.display()))?;
for (key, value) in source_properties {
snapshot.properties.insert(key, value);
}
Ok(())
}
pub fn apply_all(&mut self, snapshot: &mut InstanceSnapshot) {
pub fn apply_all(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
self.apply_ignore_unknown_instances(snapshot);
self.apply_properties(snapshot);
self.apply_properties(snapshot)?;
Ok(())
}
// TODO: Add method to allow selectively applying parts of metadata and
@@ -71,37 +76,50 @@ pub struct DirectoryMetadata {
pub ignore_unknown_instances: Option<bool>,
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
pub properties: HashMap<String, UnresolvedRbxValue>,
pub properties: HashMap<String, UnresolvedValue>,
#[serde(skip_serializing_if = "Option::is_none")]
pub class_name: Option<String>,
#[serde(skip)]
pub path: PathBuf,
}
impl DirectoryMetadata {
pub fn from_slice(slice: &[u8], path: &Path) -> anyhow::Result<Self> {
serde_json::from_slice(slice).with_context(|| {
pub fn from_slice(slice: &[u8], path: PathBuf) -> anyhow::Result<Self> {
let mut meta: Self = serde_json::from_slice(slice).with_context(|| {
format!(
"File contained malformed init.meta.json data: {}",
path.display()
)
})
})?;
meta.path = path;
Ok(meta)
}
pub fn apply_all(&mut self, snapshot: &mut InstanceSnapshot) {
pub fn apply_all(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
self.apply_ignore_unknown_instances(snapshot);
self.apply_class_name(snapshot);
self.apply_properties(snapshot);
self.apply_class_name(snapshot)?;
self.apply_properties(snapshot)?;
Ok(())
}
fn apply_class_name(&mut self, snapshot: &mut InstanceSnapshot) {
fn apply_class_name(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
if let Some(class_name) = self.class_name.take() {
if snapshot.class_name != "Folder" {
// TODO: Turn into error type
panic!("className in init.meta.json can only be specified if the affected directory would turn into a Folder instance.");
return Err(format_err!(
"className in init.meta.json can only be specified if the \
affected directory would turn into a Folder instance."
));
}
snapshot.class_name = Cow::Owned(class_name);
}
Ok(())
}
fn apply_ignore_unknown_instances(&mut self, snapshot: &mut InstanceSnapshot) {
@@ -110,17 +128,17 @@ impl DirectoryMetadata {
}
}
fn apply_properties(&mut self, snapshot: &mut InstanceSnapshot) {
let class_name = &snapshot.class_name;
fn apply_properties(&mut self, snapshot: &mut InstanceSnapshot) -> anyhow::Result<()> {
let path = &self.path;
let source_properties = self.properties.drain().map(|(key, value)| {
try_resolve_value(class_name, &key, &value)
.map(|resolved| (key, resolved))
.expect("TODO: Handle rbx_reflection errors")
});
for (key, unresolved) in self.properties.drain() {
let value = unresolved
.resolve(&snapshot.class_name, &key)
.with_context(|| format!("error applying meta file {}", path.display()))?;
for (key, value) in source_properties {
snapshot.properties.insert(key, value);
}
Ok(())
}
}