tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lib.rs (2494B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 use fluent_langneg::negotiate::NegotiationStrategy as LangNegNegotiationStrategy;
      6 use fluent_langneg::negotiate_languages;
      7 use nsstring::nsACString;
      8 use nsstring::nsCString;
      9 use thin_vec::ThinVec;
     10 use unic_langid::{LanguageIdentifier, LanguageIdentifierError};
     11 use unic_langid_ffi::new_langid_for_mozilla;
     12 
     13 /// We want to return the exact strings that were passed to us out of the
     14 /// available and default pool. Since for the negotiation we canonicalize them
     15 /// in `LanguageIdentifier`, this struct will preserve the original, non-canonicalized
     16 /// string, and then use it to populate return array.
     17 #[derive(Debug, PartialEq)]
     18 struct LangIdString<'l> {
     19    pub source: &'l nsCString,
     20    pub langid: LanguageIdentifier,
     21 }
     22 
     23 impl<'l> LangIdString<'l> {
     24    pub fn try_new(s: &'l nsCString) -> Result<Self, LanguageIdentifierError> {
     25        new_langid_for_mozilla(s).map(|l| LangIdString {
     26            source: s,
     27            langid: l,
     28        })
     29    }
     30 }
     31 
     32 impl<'l> AsRef<LanguageIdentifier> for LangIdString<'l> {
     33    fn as_ref(&self) -> &LanguageIdentifier {
     34        &self.langid
     35    }
     36 }
     37 
     38 #[repr(C)]
     39 pub enum NegotiationStrategy {
     40    Filtering,
     41    Matching,
     42    Lookup,
     43 }
     44 
     45 fn get_strategy(input: NegotiationStrategy) -> LangNegNegotiationStrategy {
     46    match input {
     47        NegotiationStrategy::Filtering => LangNegNegotiationStrategy::Filtering,
     48        NegotiationStrategy::Matching => LangNegNegotiationStrategy::Matching,
     49        NegotiationStrategy::Lookup => LangNegNegotiationStrategy::Lookup,
     50    }
     51 }
     52 
     53 #[no_mangle]
     54 pub extern "C" fn fluent_langneg_negotiate_languages(
     55    requested: &ThinVec<nsCString>,
     56    available: &ThinVec<nsCString>,
     57    default: &nsACString,
     58    strategy: NegotiationStrategy,
     59    result: &mut ThinVec<nsCString>,
     60 ) {
     61    let requested = requested
     62        .iter()
     63        .filter_map(|s| new_langid_for_mozilla(s).ok())
     64        .collect::<Vec<_>>();
     65 
     66    let available = available
     67        .iter()
     68        .filter_map(|s| LangIdString::try_new(s).ok())
     69        .collect::<Vec<_>>();
     70 
     71    let d: nsCString = default.into();
     72    let default = LangIdString::try_new(&d).ok();
     73 
     74    let strategy = get_strategy(strategy);
     75 
     76    for l in negotiate_languages(&requested, &available, default.as_ref(), strategy) {
     77        result.push(l.source.clone());
     78    }
     79 }