Skip to content

Commit

Permalink
Improvements for i18n-embed LanguageRequester
Browse files Browse the repository at this point in the history
- bump i18n-embed to v0.1.10
- bump i18n-build to v0.4.1
- bump i18n-embed to v0.6.0
  • Loading branch information
kellpossible committed May 20, 2020
1 parent 59dd6fc commit 913f82b
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 38 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ license = "MIT"
name = "cargo-i18n"
readme = "README.md"
repository = "https://github.com/kellpossible/cargo-i18n"
version = "0.1.9"
version = "0.1.10"

[badges]
maintenance = { status = "actively-developed" }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
i18n-embed = { version = "0.5", path = "./i18n-embed", features = ["desktop-requester"] }
i18n-embed = { version = "0.6", path = "./i18n-embed", features = ["desktop-requester"] }
i18n-build = { version = "0.4", path = "./i18n-build", features = ["localize"] }
i18n-config = { version = "0.2", path = "./i18n-config" }
anyhow = "1.0"
gettext = "0.4"
tr = { version = "0.1", default-features = false, features = ["gettext"] }
clap = "2.33.0"
clap = "2.33"
rust-embed = "5"
unic-langid = "0.9"
env_logger = "0.7.1"
Expand Down
4 changes: 4 additions & 0 deletions i18n-build/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog for `i18n-build`

## v0.4.1

+ Update to `i18n-embed` version `0.6.0`.

## v0.4.0

+ Update to `i18n-embed` version `0.5.0`.
Expand Down
4 changes: 2 additions & 2 deletions i18n-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license = "MIT"
name = "i18n-build"
readme = "README.md"
repository = "https://github.com/kellpossible/cargo-i18n/tree/master/i18n-build"
version = "0.4.0"
version = "0.4.1"

[package.metadata.docs.rs]
all-features = true
Expand All @@ -24,7 +24,7 @@ anyhow = "1"
thiserror = "1"
tr = { version = "0.1", default-features = false, features = ["gettext"] }
walkdir = "2"
i18n-embed = { version = "0.5", path = "../i18n-embed", features = ["desktop-requester"], optional = true }
i18n-embed = { version = "0.6", path = "../i18n-embed", features = ["desktop-requester"], optional = true }
i18n-config = { version = "0.2", path = "../i18n-config" }
gettext = { version = "0.4", optional = true }
log = "0.4"
Expand Down
5 changes: 5 additions & 0 deletions i18n-embed/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog for `i18n-embed`

## v0.6.0

+ Changed the argument for `LanguageRequester::add_listener()` to use a `std::rc::Weak` instead of `std::rc::Rc` to make it more obvious that it is the caller's responsibility to hold on to the `Rc` in order to maintain the reference.
+ Fixed typo in `LanguageRequester::set_language_override()`.

## v0.5.0

+ Refactored `I18nEmbedError::Multiple(Box<Vec<I18nEmbedError>>)` to `I18nEmbedError::Multiple(Vec<I18nEmbedError>)`, removing the useless box (and complaining Clippy lint).
Expand Down
2 changes: 1 addition & 1 deletion i18n-embed/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ license = "MIT"
name = "i18n-embed"
readme = "README.md"
repository = "https://github.com/kellpossible/cargo-i18n/tree/master/i18n-embed"
version = "0.5.0"
version = "0.6.0"

[package.metadata.docs.rs]
all-features = true
Expand Down
95 changes: 69 additions & 26 deletions i18n-embed/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
//! let localizer_rc: Rc<dyn Localizer> = Rc::new(localizer);
//!
//! let mut language_requester = DesktopLanguageRequester::new();
//! language_requester.add_listener(&localizer_rc);
//! language_requester.add_listener(Rc::downgrade(&localizer_rc));
//!
//! // Manually check the currently requested system language,
//! // and update the listeners. When the system language changes,
Expand Down Expand Up @@ -239,7 +239,10 @@ extern crate i18n_embed_impl;
pub use i18n_embed_impl::*;

use std::borrow::Cow;
use std::rc::{Rc, Weak};
use std::{
collections::{HashMap, HashSet},
rc::Weak,
};

use fluent_langneg::{negotiate_languages, NegotiationStrategy};
use log::{debug, error, info};
Expand Down Expand Up @@ -340,16 +343,16 @@ impl<'a> LanguageRequesterImpl<'a> {
/// Set an override for the requested language which is used when the
/// [LanguageRequesterImpl#poll()](LanguageRequester#poll()) method
/// is called. If `None`, then no override is used.
fn set_languge_override(
fn set_language_override(
&mut self,
language_override: Option<unic_langid::LanguageIdentifier>,
) -> Result<(), I18nEmbedError> {
self.language_override = language_override;
Ok(())
}

fn add_listener(&mut self, localizer: &Rc<dyn Localizer<'a>>) {
self.listeners.push(Rc::downgrade(localizer));
fn add_listener(&mut self, localizer: Weak<dyn Localizer<'a>>) {
self.listeners.push(localizer);
}

/// With the provided `requested_languages` call
Expand Down Expand Up @@ -387,7 +390,7 @@ impl<'a> LanguageRequesterImpl<'a> {
/// With the provided `requested_languages` call
/// [Localizer#select()](Localizer#select()) on each of the
/// listeners. The `requested_languages` may be ignored if
/// [#set_languge_override()](#set_languge_override()) has been
/// [#set_language_override()](#set_language_override()) has been
/// set.
pub fn poll(
&mut self,
Expand All @@ -403,6 +406,36 @@ impl<'a> LanguageRequesterImpl<'a> {

self.poll_without_override(languages)
}

/// The languages reported to be available in the
/// listener [Localizer](Localizer)s.
fn available_languages(&self) -> Result<Vec<unic_langid::LanguageIdentifier>, I18nEmbedError> {
let mut available_languages = HashSet::new();
for weak_listener in &self.listeners {
if let Some(localizer) = weak_listener.upgrade() {
localizer
.available_languages()?
.iter()
.for_each(|language| {
available_languages.insert(language.clone());
})
}
}

Ok(available_languages.into_iter().collect())
}

fn current_languages(&self) -> HashMap<&'static str, unic_langid::LanguageIdentifier> {
let mut current_languages = HashMap::new();
for weak_listener in &self.listeners {
if let Some(localizer) = weak_listener.upgrade() {
let loader = localizer.language_loader();
current_languages.insert(loader.domain(), loader.current_language());
}
}

current_languages
}
}

/// A trait used by [I18nEmbed](I18nEmbed) to ascertain which
Expand All @@ -416,31 +449,25 @@ pub trait LanguageRequester<'a> {
/// If you haven't already selected a language for the localizer
/// you are adding here, you may want to manually call
/// [#poll()](#poll()) after adding the listener/s.
fn add_listener(&mut self, localizer: &Rc<dyn Localizer<'a>>);
fn add_listener(&mut self, localizer: Weak<dyn Localizer<'a>>);
/// Poll the system's currently selected language, and call
/// [Localizer#select()](Localizer#select()) on each of the
/// listeners.
fn poll(&mut self) -> Result<(), I18nEmbedError>;
/// Override the languages fed to the [Localizer](Localizer) listeners during
/// a [#poll()](#poll()). Set this as `None` to disable the override.
fn set_languge_override(
fn set_language_override(
&mut self,
language_override: Option<unic_langid::LanguageIdentifier>,
) -> Result<(), I18nEmbedError>;
/// Get the language last selected for the [LanguageLoader](LanguageLoader)
/// by this [LanguageRequester](LanguageRequester).
// fn currently_selected_language(&self, language_loader: &'a dyn LanguageLoader) -> &Option<unic_langid::LanguageIdentifier>;
// fn override_request(&self, language_id: unic_langid::LanguageIdentifier);
// fn reset_override_request(&self);
// /// Attach a listener to the system this requester is mediating
// /// for, to listen for changes, and trigger a language update if
// /// required.
// fn attach_system_listener(&self) -> Result<(), Box<dyn std::error::Error>>;
// /// Detach the listener which was attached using
// /// [attach_change_listener()](#attach_change_lister()).
// fn detatch_system_listener(&self) -> Result<(), Box<dyn std::error::Error>>;
/// The currently requested languages.
fn requested_languages(&self) -> Vec<unic_langid::LanguageIdentifier>;
/// The languages reported to be available in the
/// listener [Localizer](Localizer)s.
fn available_languages(&self) -> Result<Vec<unic_langid::LanguageIdentifier>, I18nEmbedError>;
/// The languages currently loaded, keyed by the
/// [LanguageLoader::domain()](LanguageLoader::domain()).
fn current_languages(&self) -> HashMap<&'static str, unic_langid::LanguageIdentifier>;
}

/// Select the most suitable language currently requested by the
Expand Down Expand Up @@ -655,20 +682,28 @@ impl<'a> LanguageRequester<'a> for DesktopLanguageRequester<'a> {
Self::requested_languages()
}

fn add_listener(&mut self, localizer: &Rc<dyn Localizer<'a>>) {
fn add_listener(&mut self, localizer: Weak<dyn Localizer<'a>>) {
self.implementation.add_listener(localizer)
}

fn set_languge_override(
fn set_language_override(
&mut self,
language_override: Option<unic_langid::LanguageIdentifier>,
) -> Result<(), I18nEmbedError> {
self.implementation.set_languge_override(language_override)
self.implementation.set_language_override(language_override)
}

fn poll(&mut self) -> Result<(), I18nEmbedError> {
self.implementation.poll(self.requested_languages())
}

fn available_languages(&self) -> Result<Vec<unic_langid::LanguageIdentifier>, I18nEmbedError> {
self.implementation.available_languages()
}

fn current_languages(&self) -> HashMap<&'static str, unic_langid::LanguageIdentifier> {
self.implementation.current_languages()
}
}

#[cfg(feature = "desktop-requester")]
Expand Down Expand Up @@ -747,19 +782,27 @@ impl<'a> LanguageRequester<'a> for WebLanguageRequester<'a> {
Self::requested_languages()
}

fn add_listener(&mut self, localizer: &Rc<dyn Localizer<'a>>) {
fn add_listener(&mut self, localizer: Weak<dyn Localizer<'a>>) {
self.implementation.add_listener(localizer)
}

fn poll(&mut self) -> Result<(), I18nEmbedError> {
self.implementation.poll(self.requested_languages())
}

fn set_languge_override(
fn set_language_override(
&mut self,
language_override: Option<unic_langid::LanguageIdentifier>,
) -> Result<(), I18nEmbedError> {
self.implementation.set_languge_override(language_override)
self.implementation.set_language_override(language_override)
}

fn available_languages(&self) -> Result<Vec<unic_langid::LanguageIdentifier>, I18nEmbedError> {
self.implementation.available_languages()
}

fn current_languages(&self) -> HashMap<&'static str, unic_langid::LanguageIdentifier> {
self.implementation.current_languages()
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ fn main() -> Result<()> {
let cargo_i18n_localizer_rc: Rc<dyn Localizer> = Rc::new(cargo_i18n_localizer);
let i18n_build_localizer_rc = Rc::new(i18n_build::localizer()) as Rc<dyn Localizer<'static>>;

language_requester.add_listener(&cargo_i18n_localizer_rc);
language_requester.add_listener(&i18n_build_localizer_rc);
language_requester.add_listener(Rc::downgrade(&cargo_i18n_localizer_rc));
language_requester.add_listener(Rc::downgrade(&i18n_build_localizer_rc));
language_requester.poll()?;

let src_locale = LANGUAGE_LOADER.src_locale().to_string();
Expand Down Expand Up @@ -150,7 +150,7 @@ fn main() -> Result<()> {
.expect("expected a default language to be present");

let li: LanguageIdentifier = language.parse()?;
language_requester.set_languge_override(Some(li))?;
language_requester.set_language_override(Some(li))?;
language_requester.poll()?;

let path = i18n_matches
Expand Down

0 comments on commit 913f82b

Please sign in to comment.