diff options
Diffstat (limited to 'intl/locale/rust/unic-langid-ffi/src')
-rw-r--r-- | intl/locale/rust/unic-langid-ffi/src/lib.rs | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/intl/locale/rust/unic-langid-ffi/src/lib.rs b/intl/locale/rust/unic-langid-ffi/src/lib.rs new file mode 100644 index 0000000000..804a4341e1 --- /dev/null +++ b/intl/locale/rust/unic-langid-ffi/src/lib.rs @@ -0,0 +1,168 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use nsstring::{nsACString, nsCStr, nsCString}; +use thin_vec::ThinVec; +pub use unic_langid::{subtags, CharacterDirection, LanguageIdentifier, LanguageIdentifierError}; + +pub fn new_langid_for_mozilla( + name: &nsACString, +) -> Result<LanguageIdentifier, LanguageIdentifierError> { + if name.eq_ignore_ascii_case(b"ja-jp-mac") { + "ja-JP-macos".parse() + } else { + // Cut out any `.FOO` like `en-US.POSIX`. + let mut name: &[u8] = name.as_ref(); + if let Some(ptr) = name.iter().position(|b| b == &b'.') { + name = &name[..ptr]; + } + LanguageIdentifier::from_bytes(name) + } +} + +#[no_mangle] +pub extern "C" fn unic_langid_canonicalize(name: &mut nsACString) -> bool { + let langid = new_langid_for_mozilla(name); + + let result = langid.is_ok(); + + name.assign(&langid.unwrap_or_default().to_string()); + + result +} + +#[no_mangle] +pub extern "C" fn unic_langid_new( + name: &nsACString, + ret_val: &mut bool, +) -> *mut LanguageIdentifier { + let langid = new_langid_for_mozilla(name); + + *ret_val = langid.is_ok(); + Box::into_raw(Box::new(langid.unwrap_or_default())) +} + +#[no_mangle] +pub unsafe extern "C" fn unic_langid_destroy(langid: *mut LanguageIdentifier) { + let _ = Box::from_raw(langid); +} + +#[no_mangle] +pub extern "C" fn unic_langid_as_string(langid: &mut LanguageIdentifier, ret_val: &mut nsACString) { + ret_val.assign(&langid.to_string()); +} + +#[no_mangle] +pub extern "C" fn unic_langid_get_language<'a>( + langid: &'a LanguageIdentifier, + out: &mut nsCStr<'a>, +) { + *out = nsCStr::from(langid.language.as_str()); +} + +#[no_mangle] +pub extern "C" fn unic_langid_set_language( + langid: &mut LanguageIdentifier, + string: &nsACString, +) -> bool { + subtags::Language::from_bytes(string) + .map(|lang| langid.language = lang) + .is_ok() +} + +#[no_mangle] +pub extern "C" fn unic_langid_clear_language(langid: &mut LanguageIdentifier) { + langid.language.clear() +} + +#[no_mangle] +pub extern "C" fn unic_langid_get_script<'a>(langid: &'a LanguageIdentifier, out: &mut nsCStr<'a>) { + *out = nsCStr::from(langid.script.as_ref().map_or("", |s| s.as_str())); +} + +#[no_mangle] +pub extern "C" fn unic_langid_set_script( + langid: &mut LanguageIdentifier, + string: &nsACString, +) -> bool { + subtags::Script::from_bytes(string) + .map(|script| langid.script = Some(script)) + .is_ok() +} + +#[no_mangle] +pub extern "C" fn unic_langid_clear_script(langid: &mut LanguageIdentifier) { + langid.script = None; +} + +#[no_mangle] +pub extern "C" fn unic_langid_get_region<'a>(langid: &'a LanguageIdentifier, out: &mut nsCStr<'a>) { + *out = nsCStr::from(langid.region.as_ref().map_or("", |s| s.as_str())); +} + +#[no_mangle] +pub extern "C" fn unic_langid_set_region( + langid: &mut LanguageIdentifier, + string: &nsACString, +) -> bool { + subtags::Region::from_bytes(string) + .map(|region| langid.region = Some(region)) + .is_ok() +} + +#[no_mangle] +pub extern "C" fn unic_langid_clear_region(langid: &mut LanguageIdentifier) { + langid.region = None; +} + +#[no_mangle] +pub extern "C" fn unic_langid_get_variants( + langid: &LanguageIdentifier, + variants: &mut ThinVec<nsCString>, +) { + for v in langid.variants() { + variants.push(v.as_str().into()); + } +} + +#[no_mangle] +pub extern "C" fn unic_langid_set_variants( + langid: &mut LanguageIdentifier, + variants: &ThinVec<nsCString>, +) -> bool { + variants + .iter() + .map(|v| subtags::Variant::from_bytes(v)) + .collect::<Result<Vec<_>, _>>() + .map(|variants| langid.set_variants(&variants)) + .is_ok() +} + +#[no_mangle] +pub extern "C" fn unic_langid_clear_variants(langid: &mut LanguageIdentifier) { + langid.clear_variants() +} + +#[no_mangle] +pub extern "C" fn unic_langid_matches( + langid: &LanguageIdentifier, + other: &LanguageIdentifier, + self_as_range: bool, + other_as_range: bool, +) -> bool { + langid.matches(other, self_as_range, other_as_range) +} + +#[no_mangle] +pub extern "C" fn unic_langid_maximize(langid: &mut LanguageIdentifier) -> bool { + langid.maximize() +} + +#[no_mangle] +pub extern "C" fn unic_langid_is_rtl(name: &nsACString) -> bool { + match new_langid_for_mozilla(name) { + Ok(langid) => langid.character_direction() == CharacterDirection::RTL, + Err(_) => false, + } +} |