Disambiguate camelCase and PascalCase in *.meta.json and *.model.json (#563)

* Disambiguate camelCase and PascalCase.

*.meta.json forces camelCase while *.model.json forces PascalCase. This commit reinforces camelCase as the preference for both, but allows for PascalCase in both as well.

* Made requested changes, breaking due to serde bug.

* Make work with existing Serde stuff

* Work around MSRV

Co-authored-by: Lucien Greathouse <me@lpghatguy.com>
This commit is contained in:
Max
2022-06-29 19:14:35 -05:00
committed by GitHub
parent 966478b131
commit f649c180cf
3 changed files with 103 additions and 30 deletions

View File

@@ -8,7 +8,7 @@ homepage = "https://rojo.space"
documentation = "https://rojo.space/docs" documentation = "https://rojo.space/docs"
repository = "https://github.com/rojo-rbx/rojo" repository = "https://github.com/rojo-rbx/rojo"
readme = "README.md" readme = "README.md"
edition = "2018" edition = "2021"
build = "build.rs" build = "build.rs"
exclude = [ exclude = [

View File

@@ -26,12 +26,25 @@ pub fn snapshot_json_model(
return Ok(None); return Ok(None);
} }
let instance: JsonModel = serde_json::from_str(contents_str) let mut instance: JsonModel = serde_json::from_str(contents_str)
.with_context(|| format!("File is not a valid JSON model: {}", path.display()))?; .with_context(|| format!("File is not a valid JSON model: {}", path.display()))?;
if let Some(top_level_name) = &instance.name {
let new_name = format!("{}.model.json", top_level_name);
log::warn!(
"Model at path {} had a top-level Name field. \
This field has been ignored since Rojo 6.0.\n\
Consider removing this field and renaming the file to {}.",
new_name,
path.display()
);
}
instance.name = Some(name.to_owned());
let mut snapshot = instance let mut snapshot = instance
.core .into_snapshot()
.into_snapshot(name.to_owned())
.with_context(|| format!("Could not load JSON model: {}", path.display()))?; .with_context(|| format!("Could not load JSON model: {}", path.display()))?;
snapshot.metadata = snapshot snapshot.metadata = snapshot
@@ -44,42 +57,37 @@ pub fn snapshot_json_model(
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")] #[serde(rename_all = "camelCase")]
struct JsonModel { struct JsonModel {
#[serde(alias = "Name")]
name: Option<String>, name: Option<String>,
#[serde(flatten)] #[serde(alias = "ClassName")]
core: JsonModelCore,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct JsonModelInstance {
name: String,
#[serde(flatten)]
core: JsonModelCore,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct JsonModelCore {
class_name: String, class_name: String,
#[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] #[serde(
children: Vec<JsonModelInstance>, alias = "Children",
default = "Vec::new",
skip_serializing_if = "Vec::is_empty"
)]
children: Vec<JsonModel>,
#[serde(default = "HashMap::new", skip_serializing_if = "HashMap::is_empty")] #[serde(
alias = "Properties",
default = "HashMap::new",
skip_serializing_if = "HashMap::is_empty"
)]
properties: HashMap<String, UnresolvedValue>, properties: HashMap<String, UnresolvedValue>,
} }
impl JsonModelCore { impl JsonModel {
fn into_snapshot(self, name: String) -> anyhow::Result<InstanceSnapshot> { fn into_snapshot(self) -> anyhow::Result<InstanceSnapshot> {
let name = self.name.unwrap_or_else(|| self.class_name.clone());
let class_name = self.class_name; let class_name = self.class_name;
let mut children = Vec::with_capacity(self.children.len()); let mut children = Vec::with_capacity(self.children.len());
for child in self.children { for child in self.children {
children.push(child.core.into_snapshot(child.name)?); children.push(child.into_snapshot()?);
} }
let mut properties = HashMap::with_capacity(self.properties.len()); let mut properties = HashMap::with_capacity(self.properties.len());
@@ -113,7 +121,43 @@ mod test {
VfsSnapshot::file( VfsSnapshot::file(
r#" r#"
{ {
"Name": "children", "className": "IntValue",
"properties": {
"Value": 5
},
"children": [
{
"name": "The Child",
"className": "StringValue"
}
]
}
"#,
),
)
.unwrap();
let vfs = Vfs::new(imfs);
let instance_snapshot = snapshot_json_model(
&InstanceContext::default(),
&vfs,
Path::new("/foo.model.json"),
)
.unwrap()
.unwrap();
insta::assert_yaml_snapshot!(instance_snapshot);
}
#[test]
fn model_from_vfs_legacy() {
let mut imfs = InMemoryFs::new();
imfs.load_snapshot(
"/foo.model.json",
VfsSnapshot::file(
r#"
{
"ClassName": "IntValue", "ClassName": "IntValue",
"Properties": { "Properties": {
"Value": 5 "Value": 5
@@ -130,11 +174,11 @@ mod test {
) )
.unwrap(); .unwrap();
let mut vfs = Vfs::new(imfs); let vfs = Vfs::new(imfs);
let instance_snapshot = snapshot_json_model( let instance_snapshot = snapshot_json_model(
&InstanceContext::default(), &InstanceContext::default(),
&mut vfs, &vfs,
Path::new("/foo.model.json"), Path::new("/foo.model.json"),
) )
.unwrap() .unwrap()

View File

@@ -0,0 +1,29 @@
---
source: src/snapshot_middleware/json_model.rs
assertion_line: 186
expression: instance_snapshot
---
snapshot_id: ~
metadata:
ignore_unknown_instances: false
instigating_source:
Path: /foo.model.json
relevant_paths:
- /foo.model.json
context: {}
name: foo
class_name: IntValue
properties:
Value:
Int64: 5
children:
- snapshot_id: ~
metadata:
ignore_unknown_instances: false
relevant_paths: []
context: {}
name: The Child
class_name: StringValue
properties: {}
children: []