diff --git a/executors/rust/1.3/src/listfmt.rs b/executors/rust/1.3/src/listfmt.rs new file mode 100644 index 00000000..ee9227de --- /dev/null +++ b/executors/rust/1.3/src/listfmt.rs @@ -0,0 +1,94 @@ +//! Executor provides tests for list formatting in locale-sensitive manner. + +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value}; + +use icu::list::*; +use icu::locid::Locale; + +use writeable::Writeable; + +#[derive(Deserialize, Serialize, Debug)] +#[serde(rename_all = "snake_case")] +struct ListFormatOptions { + style: Option, + list_type: Option, +} + +// Function runs list format tests +pub fn run_list_fmt_test(json_obj: &Value) -> Result { + let label = &json_obj["label"].as_str().unwrap(); + + let locale_str: &str = json_obj["locale"].as_str().unwrap(); + let locale = locale_str.parse::().unwrap(); + + let options = &json_obj["options"]; // This will be an array. + let option_struct: ListFormatOptions = serde_json::from_str(&options.to_string()).unwrap(); + + let style: &str = option_struct.style.as_ref().unwrap(); + let list_type: &str = option_struct.list_type.as_ref().unwrap(); + + // get input list + + // Style + let list_style: ListLength = if style == "long" { + ListLength::Wide + } else if style == "short" { + ListLength::Short + } else if style == "narrow" { + ListLength::Narrow + } else { + // Report an unsupported option. + return Ok(json!({ + "label": label, + "error_detail": {"option": style}, + "unsupported": "unknown list style", + "error_type": "unsupported", + })); + }; + + let list_formatter_result: Result = if list_type == "conjunction" { + // Reference: https://docs.rs/icu/latest/icu/list/index.html + ListFormatter::try_new_and_with_length(&locale.into(), list_style) + } else if list_type == "disjunction" { + ListFormatter::try_new_or_with_length(&locale.into(), list_style) + } else if list_type == "unit" { + ListFormatter::try_new_unit_with_length(&locale.into(), list_style) + } else { + // This option is not supported. + return Ok(json!({ + "label": label, + "error_detail": {"option": list_type}, + "unsupported": "unknown format type", + "error_type": "unsupported", + })); + }; + + // Data to be formatted. + let input_list = json_obj["input_list"].as_array().unwrap(); + let input_list_str_iter = input_list + .iter() + .map(|json_value| json_value.as_str().unwrap()); + + let json_result = match list_formatter_result { + Ok(formatter) => { + json!({ + "label": label, + "result": formatter.format( + input_list_str_iter).write_to_string().into_owned() + }) + } + Err(e) => { + json!({ + "label": label, + "locale_label": locale_str, + "error": e.to_string(), + "error_type": "unsupported", + "unsupported": e.to_string(), + "error_detail": {"unsupported_locale": locale_str} + }) + } + }; + + Ok(json_result) +} diff --git a/executors/rust/1.3/src/main.rs b/executors/rust/1.3/src/main.rs index 9fe5d6d2..11c261da 100644 --- a/executors/rust/1.3/src/main.rs +++ b/executors/rust/1.3/src/main.rs @@ -21,11 +21,13 @@ mod decimalfmt; mod displaynames; mod langnames; mod likelysubtags; +mod listfmt; mod numberfmt; use collator::run_collation_test; use langnames::run_language_name_test; use likelysubtags::run_likelysubtags_test; +use listfmt::run_list_fmt_test; use numberfmt::run_numberformat_test; use serde_json::{json, Value}; @@ -68,7 +70,9 @@ fn main() -> io::Result<()> { "collation_short", "number_fmt", "decimal_fmt", - "likelysubtags"] } + "likelysubtags", + "list_fmt" + ] } ); println!("{}", json_result); } @@ -103,6 +107,8 @@ fn main() -> io::Result<()> { run_language_name_test(&json_info) } else if test_type == "likely_subtags" { run_likelysubtags_test(&json_info) + } else if test_type == "list_fmt" { + run_list_fmt_test(&json_info) } else { Err(test_type.to_string()) }; diff --git a/executors/test_strings.txt b/executors/test_strings.txt index 8601a03b..13eae62d 100644 --- a/executors/test_strings.txt +++ b/executors/test_strings.txt @@ -285,8 +285,8 @@ {"test_type": "list_fmt", "label":"en_-GB 2000", "input_string": "2000-01-01T21:00:00.000Z","input_list":[],"options":{"style":"long","type":"conjunction"},"locale":"en-GB"} -{"test_type": "list_fmt", "label":"12","input_list":["dog","cat"],"options":{"style":"narrow","type":"conjunction"},"locale":"en-GB"} -{"test_type": "list_fmt", "label":"12","input_list":["dog","cat","fish"],"options":{"style":"long","type":"conjunction"},"locale":"en-GB"} +{"test_type": "list_fmt", "label":"12","input_list":["dog","cat"],"options":{"style":"narrow","list_type":"conjunction", "type":"conjunction"},"locale":"en-GB"} +{"test_type": "list_fmt", "label":"12","input_list":["dog","cat","fish"],"options":{"style":"long","list_type":"conjunction"},"locale":"en-GB"} {"test_type": "list_fmt", "label":"12","input_list":["dog","cat","fish"],"options":{"style":"long","type":"disjunction"},"locale":"en-GB"} {"test_type": "list_fmt", "label":"12","input_list":["dog","cat","fish"],"options":{"style":"long","type":"unit"},"locale":"en-GB"} diff --git a/run_config.json b/run_config.json index 90bbef76..f77208ea 100644 --- a/run_config.json +++ b/run_config.json @@ -230,7 +230,8 @@ "collation_short", "number_fmt", "lang_names", - "likely_subtags" + "likely_subtags", + "list_fmt" ], "per_execution": 10000 } @@ -246,9 +247,10 @@ "exec": "rust", "test_type": [ "collation_short", - "number_fmt", "lang_names", - "likely_subtags" + "list_fmt", + "likely_subtags", + "number_fmt" ], "per_execution": 10000 } diff --git a/schema/list_fmt/test_schema.json b/schema/list_fmt/test_schema.json index 530bd17f..b0ef2a7d 100644 --- a/schema/list_fmt/test_schema.json +++ b/schema/list_fmt/test_schema.json @@ -96,6 +96,11 @@ "enum": ["long", "short", "narrow"] }, "type": { + "description": "Deprecated! The kind of connection between list items, e.g., and/or/none", + "type": "string", + "enum": ["conjunction", "disjunction", "unit"] + }, + "list_type": { "description": "The kind of connection between list items, e.g., and/or/none", "type": "string", "enum": ["conjunction", "disjunction", "unit"] diff --git a/testgen/generators/list_fmt_gen.js b/testgen/generators/list_fmt_gen.js index 08f5b25c..c0ad841e 100644 --- a/testgen/generators/list_fmt_gen.js +++ b/testgen/generators/list_fmt_gen.js @@ -78,7 +78,8 @@ function generateAll() { // Create format object with these options let all_options = { 'style': style, - 'type': type + 'list_type': type, // Needed because "type" is a reserved word in Rust + 'type': type // Backward compatible } let formatter;