From 0be4e6921dfa9baf384f124865fa10c5ec1d218e Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Tue, 8 Jan 2019 18:16:04 -0800 Subject: [PATCH] Implement CSV-format LocalizationTable serialization --- server/Cargo.lock | 20 +++++++++++ server/Cargo.toml | 1 + server/single-sync-point.rbxl | Bin 0 -> 881 bytes server/src/rbx_session.rs | 62 ++++++++++++++++++++++++++++++++-- 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 server/single-sync-point.rbxl diff --git a/server/Cargo.lock b/server/Cargo.lock index 0ce3fc03..8f184fa4 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -280,6 +280,23 @@ dependencies = [ "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "csv" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "csv-core" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "deflate" version = "0.7.19" @@ -1189,6 +1206,7 @@ name = "rojo" version = "0.5.0" dependencies = [ "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1905,6 +1923,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" "checksum crossbeam-epoch 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f10a4f8f409aaac4b16a5474fb233624238fcdeefb9ba50d5ea059aab63ba31c" "checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a" +"checksum csv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd1c44c58078cfbeaf11fbb3eac9ae5534c23004ed770cc4bfb48e658ae4f04" +"checksum csv-core 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa5cdef62f37e6ffe7d1f07a381bc0db32b7a3ff1cac0de56cb0d81e71f53d65" "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" "checksum encoding_rs 0.8.14 (registry+https://github.com/rust-lang/crates.io-index)" = "a69d152eaa438a291636c1971b0a370212165ca8a75759eb66818c5ce9b538f7" diff --git a/server/Cargo.toml b/server/Cargo.toml index 97c5c5d9..88bdf38e 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -21,6 +21,7 @@ bundle-plugin = [] [dependencies] clap = "2.27" +csv = "1.0" env_logger = "0.5" failure = "0.1.3" log = "0.4" diff --git a/server/single-sync-point.rbxl b/server/single-sync-point.rbxl new file mode 100644 index 0000000000000000000000000000000000000000..6890b3f60450f39fb6eff9ef8af4efd897821457 GIT binary patch literal 881 zcmZuwO>fgc5FI;7DJ?W=3$2Qv-B<-xBH<$(DuoIm0*#7Fh!S5af~u{(v{u$$W3M3) zFq6-;>9h z3DPVfV-bUpPSQAmv8kjhqNB-yh%5N{64epujEUnJj7Q2%q-Z&j7wRK=w$Xgt7~em2 zS?9hm{@cj7hW39#6LUY5!j5r4tdhuChV|af{t66UaG8kMs`MmRKa6i5YCPafNG6^qUZ`#WY(e%dLjD@e z<_{qUHOM)}zhgui>}gnDk9PeI+tS> zB|i58qOD(input: &'a str, trailer: &str) -> Option<&'a str> { @@ -240,11 +241,46 @@ fn classify_file(file: &ImfsFile) -> Option<(&str, FileType)> { Some((instance_name, FileType::ClientScript)) } else if let Some(instance_name) = get_trailing(file_name, ".lua") { Some((instance_name, FileType::ModuleScript)) + } else if let Some(instance_name) = get_trailing(file_name, ".csv") { + Some((instance_name, FileType::LocalizationTable)) } else { None } } +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +struct LocalizationEntryCsv { + key: String, + context: String, + example: String, + source: String, + #[serde(flatten)] + values: HashMap, +} + +impl LocalizationEntryCsv { + fn to_json(self) -> LocalizationEntryJson { + LocalizationEntryJson { + key: self.key, + context: self.context, + example: self.example, + source: self.source, + values: self.values, + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct LocalizationEntryJson { + key: String, + context: String, + example: String, + source: String, + values: HashMap, +} + // TODO: Return a Result wrapping an Option so that failure can be represented // separately from "this thing is unknown" fn snapshot_instances_from_imfs<'a>( @@ -266,15 +302,35 @@ fn snapshot_instances_from_imfs<'a>( FileType::ModuleScript => "ModuleScript", FileType::ServerScript => "Script", FileType::ClientScript => "LocalScript", + FileType::LocalizationTable => "LocalizationTable", }; let contents = str::from_utf8(&file.contents) .expect("File did not contain UTF-8 data, which is required for scripts."); let mut properties = HashMap::new(); - properties.insert(String::from("Source"), RbxValue::String { - value: contents.to_string(), - }); + + match file_type { + FileType::ModuleScript | FileType::ServerScript | FileType::ClientScript => { + properties.insert(String::from("Source"), RbxValue::String { + value: contents.to_string(), + }); + }, + FileType::LocalizationTable => { + let entries: Vec = csv::Reader::from_reader(contents.as_bytes()) + .deserialize() + .map(|result| result.expect("Malformed localization table found!")) + .map(LocalizationEntryCsv::to_json) + .collect(); + + let table_contents = serde_json::to_string(&entries) + .expect("Could not encode JSON for localization table"); + + properties.insert(String::from("Contents"), RbxValue::String { + value: table_contents, + }); + }, + } Some(RbxSnapshotInstance { name: instance_name,