Source code
Revision control
Copy as Markdown
Other Tools
use serde_json::Value;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fs;
use unic_langid_impl::subtags::Script;
use unic_langid_impl::CharacterDirection;
use unic_langid_impl::LanguageIdentifier;
fn langid_to_direction_map(path: &str) -> HashMap<LanguageIdentifier, CharacterDirection> {
let mut result = HashMap::new();
for entry in fs::read_dir(path).unwrap() {
let entry = entry.unwrap();
let mut path = entry.path();
path.push("layout.json");
let contents = fs::read_to_string(path).expect("Something went wrong reading the file");
let v: Value = serde_json::from_str(&contents).unwrap();
let langid_key = v["main"].as_object().unwrap().keys().next().unwrap();
if langid_key == "root" {
continue;
}
let langid: LanguageIdentifier = langid_key.parse().unwrap();
let character_order = match v["main"][langid_key]["layout"]["orientation"]["characterOrder"]
.as_str()
.unwrap()
{
"right-to-left" => CharacterDirection::RTL,
"left-to-right" => CharacterDirection::LTR,
"top-to-bottom" => CharacterDirection::TTB,
_ => unimplemented!("Encountered unknown directionality!"),
};
result.insert(langid, character_order);
}
result
}
fn check_all_script_variants(
map: &HashMap<LanguageIdentifier, CharacterDirection>,
exp_dir: CharacterDirection,
script: Option<Script>,
) -> bool {
for (langid, dir) in map.iter() {
if let Some(reference_script) = script {
if let Some(s) = langid.script {
if reference_script == s && *dir != exp_dir {
return false;
}
}
}
}
true
}
fn main() {
let path = "./data/cldr-misc-full/main/";
let map = langid_to_direction_map(path);
let mut scripts_ltr = HashSet::new();
let mut scripts_rtl = HashSet::new();
let mut scripts_ttb = HashSet::new();
let mut langs_rtl = HashSet::new();
for (langid, dir) in map.iter() {
let script = langid.script;
let scripts = match dir {
CharacterDirection::LTR => &mut scripts_ltr,
CharacterDirection::RTL => {
langs_rtl.insert(langid.language);
&mut scripts_rtl
}
CharacterDirection::TTB => &mut scripts_ttb,
};
if let Some(script) = script {
if scripts.contains(&script) {
continue;
}
assert!(
check_all_script_variants(&map, *dir, Some(script)),
"We didn't expect a script with two directionalities!"
);
scripts.insert(script);
continue;
}
}
let mut scripts_ltr: Vec<String> = scripts_ltr
.into_iter()
.map(|s| {
let v: u32 = s.into();
v.to_string()
})
.collect();
scripts_ltr.sort();
let mut scripts_rtl: Vec<String> = scripts_rtl
.into_iter()
.map(|s| {
let v: u32 = s.into();
v.to_string()
})
.collect();
scripts_rtl.sort();
let mut scripts_ttb: Vec<String> = scripts_ttb
.into_iter()
.map(|s| {
let v: u32 = s.into();
v.to_string()
})
.collect();
scripts_ttb.sort();
let mut langs_rtl: Vec<String> = langs_rtl
.into_iter()
.map(|s| {
let v: Option<u64> = s.into();
let v: u64 = v.expect("Expected language to not be undefined.");
v.to_string()
})
.collect();
langs_rtl.sort();
println!(
"pub const SCRIPTS_CHARACTER_DIRECTION_LTR: [u32; {}] = [{}];",
scripts_ltr.len(),
scripts_ltr.join(", ")
);
println!(
"pub const SCRIPTS_CHARACTER_DIRECTION_RTL: [u32; {}] = [{}];",
scripts_rtl.len(),
scripts_rtl.join(", ")
);
println!(
"pub const SCRIPTS_CHARACTER_DIRECTION_TTB: [u32; {}] = [{}];",
scripts_ttb.len(),
scripts_ttb.join(", ")
);
println!(
"pub const LANGS_CHARACTER_DIRECTION_RTL: [u64; {}] = [{}];",
langs_rtl.len(),
langs_rtl.join(", ")
);
}