From f649c180cf68cce4aa917126ecdf35aede852716 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 29 Jun 2022 19:14:35 -0500 Subject: [PATCH] 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 --- Cargo.toml | 2 +- src/snapshot_middleware/json_model.rs | 102 +++++++++++++----- ...on_model__test__model_from_vfs_legacy.snap | 29 +++++ 3 files changed, 103 insertions(+), 30 deletions(-) create mode 100644 src/snapshot_middleware/snapshots/librojo__snapshot_middleware__json_model__test__model_from_vfs_legacy.snap diff --git a/Cargo.toml b/Cargo.toml index 25eedb6b..34bfe1e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ homepage = "https://rojo.space" documentation = "https://rojo.space/docs" repository = "https://github.com/rojo-rbx/rojo" readme = "README.md" -edition = "2018" +edition = "2021" build = "build.rs" exclude = [ diff --git a/src/snapshot_middleware/json_model.rs b/src/snapshot_middleware/json_model.rs index 52071031..c29388c1 100644 --- a/src/snapshot_middleware/json_model.rs +++ b/src/snapshot_middleware/json_model.rs @@ -26,12 +26,25 @@ pub fn snapshot_json_model( 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()))?; + 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 - .core - .into_snapshot(name.to_owned()) + .into_snapshot() .with_context(|| format!("Could not load JSON model: {}", path.display()))?; snapshot.metadata = snapshot @@ -44,42 +57,37 @@ pub fn snapshot_json_model( } #[derive(Debug, Deserialize)] -#[serde(rename_all = "PascalCase")] +#[serde(rename_all = "camelCase")] struct JsonModel { + #[serde(alias = "Name")] name: Option, - #[serde(flatten)] - 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 { + #[serde(alias = "ClassName")] class_name: String, - #[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] - children: Vec, + #[serde( + alias = "Children", + default = "Vec::new", + skip_serializing_if = "Vec::is_empty" + )] + children: Vec, - #[serde(default = "HashMap::new", skip_serializing_if = "HashMap::is_empty")] + #[serde( + alias = "Properties", + default = "HashMap::new", + skip_serializing_if = "HashMap::is_empty" + )] properties: HashMap, } -impl JsonModelCore { - fn into_snapshot(self, name: String) -> anyhow::Result { +impl JsonModel { + fn into_snapshot(self) -> anyhow::Result { + let name = self.name.unwrap_or_else(|| self.class_name.clone()); let class_name = self.class_name; let mut children = Vec::with_capacity(self.children.len()); 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()); @@ -113,7 +121,43 @@ mod test { VfsSnapshot::file( 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", "Properties": { "Value": 5 @@ -130,11 +174,11 @@ mod test { ) .unwrap(); - let mut vfs = Vfs::new(imfs); + let vfs = Vfs::new(imfs); let instance_snapshot = snapshot_json_model( &InstanceContext::default(), - &mut vfs, + &vfs, Path::new("/foo.model.json"), ) .unwrap() diff --git a/src/snapshot_middleware/snapshots/librojo__snapshot_middleware__json_model__test__model_from_vfs_legacy.snap b/src/snapshot_middleware/snapshots/librojo__snapshot_middleware__json_model__test__model_from_vfs_legacy.snap new file mode 100644 index 00000000..a58fdb0f --- /dev/null +++ b/src/snapshot_middleware/snapshots/librojo__snapshot_middleware__json_model__test__model_from_vfs_legacy.snap @@ -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: [] +