Implement CSV-format LocalizationTable serialization

This commit is contained in:
Lucien Greathouse
2019-01-08 18:16:04 -08:00
parent 049875e8fc
commit 0be4e6921d
4 changed files with 80 additions and 3 deletions

20
server/Cargo.lock generated
View File

@@ -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"

View File

@@ -21,6 +21,7 @@ bundle-plugin = []
[dependencies]
clap = "2.27"
csv = "1.0"
env_logger = "0.5"
failure = "0.1.3"
log = "0.4"

Binary file not shown.

View File

@@ -220,6 +220,7 @@ enum FileType {
ModuleScript,
ServerScript,
ClientScript,
LocalizationTable,
}
fn get_trailing<'a>(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<String, String>,
}
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<String, String>,
}
// 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<LocalizationEntryJson> = 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,