summaryrefslogtreecommitdiffstats
path: root/vendor/unic-langid-impl/src/likelysubtags/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/unic-langid-impl/src/likelysubtags/mod.rs')
-rw-r--r--vendor/unic-langid-impl/src/likelysubtags/mod.rs136
1 files changed, 136 insertions, 0 deletions
diff --git a/vendor/unic-langid-impl/src/likelysubtags/mod.rs b/vendor/unic-langid-impl/src/likelysubtags/mod.rs
new file mode 100644
index 000000000..dad9dc9a6
--- /dev/null
+++ b/vendor/unic-langid-impl/src/likelysubtags/mod.rs
@@ -0,0 +1,136 @@
+mod tables;
+
+pub use tables::CLDR_VERSION;
+
+use crate::subtags;
+
+unsafe fn lang_from_parts(
+ input: (Option<u64>, Option<u32>, Option<u32>),
+ lang: Option<subtags::Language>,
+ script: Option<subtags::Script>,
+ region: Option<subtags::Region>,
+) -> Option<(
+ subtags::Language,
+ Option<subtags::Script>,
+ Option<subtags::Region>,
+)> {
+ let lang = lang
+ .or_else(|| input.0.map(|s| subtags::Language::from_raw_unchecked(s)))
+ .unwrap();
+ let script = script.or_else(|| input.1.map(|s| subtags::Script::from_raw_unchecked(s)));
+ let region = region.or_else(|| input.2.map(|r| subtags::Region::from_raw_unchecked(r)));
+ Some((lang, script, region))
+}
+
+pub fn maximize(
+ lang: subtags::Language,
+ script: Option<subtags::Script>,
+ region: Option<subtags::Region>,
+) -> Option<(
+ subtags::Language,
+ Option<subtags::Script>,
+ Option<subtags::Region>,
+)> {
+ if !lang.is_empty() && script.is_some() && region.is_some() {
+ return None;
+ }
+
+ if let Some(l) = Into::<Option<u64>>::into(lang) {
+ if let Some(r) = region {
+ let result = tables::LANG_REGION
+ .binary_search_by_key(&(&l.into(), &r.into()), |(key_l, key_r, _)| (key_l, key_r))
+ .ok();
+ if let Some(r) = result {
+ // safe because all table entries are well formed.
+ return unsafe { lang_from_parts(tables::LANG_REGION[r].2, None, None, None) };
+ }
+ }
+
+ if let Some(s) = script {
+ let result = tables::LANG_SCRIPT
+ .binary_search_by_key(&(&l.into(), &s.into()), |(key_l, key_s, _)| (key_l, key_s))
+ .ok();
+ if let Some(r) = result {
+ // safe because all table entries are well formed.
+ return unsafe { lang_from_parts(tables::LANG_SCRIPT[r].2, None, None, None) };
+ }
+ }
+
+ let result = tables::LANG_ONLY
+ .binary_search_by_key(&(&l.into()), |(key_l, _)| key_l)
+ .ok();
+ if let Some(r) = result {
+ // safe because all table entries are well formed.
+ return unsafe { lang_from_parts(tables::LANG_ONLY[r].1, None, script, region) };
+ }
+ } else if let Some(s) = script {
+ if let Some(r) = region {
+ let result = tables::SCRIPT_REGION
+ .binary_search_by_key(&(&s.into(), &r.into()), |(key_s, key_r, _)| (key_s, key_r))
+ .ok();
+ if let Some(r) = result {
+ // safe because all table entries are well formed.
+ return unsafe { lang_from_parts(tables::SCRIPT_REGION[r].2, None, None, None) };
+ }
+ }
+
+ let result = tables::SCRIPT_ONLY
+ .binary_search_by_key(&(&s.into()), |(key_s, _)| key_s)
+ .ok();
+ if let Some(r) = result {
+ // safe because all table entries are well formed.
+ return unsafe { lang_from_parts(tables::SCRIPT_ONLY[r].1, None, None, region) };
+ }
+ } else if let Some(r) = region {
+ let result = tables::REGION_ONLY
+ .binary_search_by_key(&(&r.into()), |(key_r, _)| key_r)
+ .ok();
+ if let Some(r) = result {
+ // safe because all table entries are well formed.
+ return unsafe { lang_from_parts(tables::REGION_ONLY[r].1, None, None, None) };
+ }
+ }
+
+ None
+}
+
+pub fn minimize(
+ lang: subtags::Language,
+ script: Option<subtags::Script>,
+ region: Option<subtags::Region>,
+) -> Option<(
+ subtags::Language,
+ Option<subtags::Script>,
+ Option<subtags::Region>,
+)> {
+ // maximize returns None when all 3 components are
+ // already filled so don't call it in that case.
+ let max_langid = if !lang.is_empty() && script.is_some() && region.is_some() {
+ (lang, script, region)
+ } else {
+ maximize(lang, script, region)?
+ };
+
+ if let Some(trial) = maximize(max_langid.0, None, None) {
+ if trial == max_langid {
+ return Some((max_langid.0, None, None));
+ }
+ }
+
+ if max_langid.2.is_some() {
+ if let Some(trial) = maximize(max_langid.0, None, max_langid.2) {
+ if trial == max_langid {
+ return Some((max_langid.0, None, max_langid.2));
+ }
+ }
+ }
+
+ if max_langid.1.is_some() {
+ if let Some(trial) = maximize(max_langid.0, max_langid.1, None) {
+ if trial == max_langid {
+ return Some((max_langid.0, max_langid.1, None));
+ }
+ }
+ }
+ None
+}