Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor fluent_args #130

Merged
merged 1 commit into from
Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 11 additions & 14 deletions fluent-bundle/benches/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,20 @@ fn get_ids(res: &FluentResource) -> Vec<String> {
.collect()
}

fn get_args(name: &str) -> Option<HashMap<String, FluentValue>> {
fn get_args(name: &str) -> Option<HashMap<&str, FluentValue>> {
match name {
"preferences" => {
let mut prefs_args = HashMap::new();
prefs_args.insert("name".to_string(), FluentValue::from("John"));
prefs_args.insert("tabCount".to_string(), FluentValue::from(5));
prefs_args.insert("count".to_string(), FluentValue::from(3));
prefs_args.insert("version".to_string(), FluentValue::from("65.0"));
prefs_args.insert("path".to_string(), FluentValue::from("/tmp"));
prefs_args.insert("num".to_string(), FluentValue::from(4));
prefs_args.insert("email".to_string(), FluentValue::from("john@doe.com"));
prefs_args.insert("value".to_string(), FluentValue::from(4.5));
prefs_args.insert("unit".to_string(), FluentValue::from("mb"));
prefs_args.insert(
"service-name".to_string(),
FluentValue::from("Mozilla Disk"),
);
prefs_args.insert("name", FluentValue::from("John"));
prefs_args.insert("tabCount", FluentValue::from(5));
prefs_args.insert("count", FluentValue::from(3));
prefs_args.insert("version", FluentValue::from("65.0"));
prefs_args.insert("path", FluentValue::from("/tmp"));
prefs_args.insert("num", FluentValue::from(4));
prefs_args.insert("email", FluentValue::from("john@doe.com"));
prefs_args.insert("value", FluentValue::from(4.5));
prefs_args.insert("unit", FluentValue::from("mb"));
prefs_args.insert("service-name", FluentValue::from("Mozilla Disk"));
Some(prefs_args)
}
_ => None,
Expand Down
11 changes: 5 additions & 6 deletions fluent-bundle/examples/external_arguments.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use fluent_bundle::{FluentBundle, FluentResource, FluentValue};
use std::collections::HashMap;
use fluent_bundle::{FluentArgs, FluentBundle, FluentResource, FluentValue};
use unic_langid::langid;

fn main() {
Expand All @@ -21,8 +20,8 @@ unread-emails =
.add_resource(res)
.expect("Failed to add FTL resources to the bundle.");

let mut args = HashMap::new();
args.insert("name".to_string(), FluentValue::from("John"));
let mut args = FluentArgs::new();
args.insert("name", FluentValue::from("John"));

let msg = bundle
.get_message("hello-world")
Expand All @@ -38,8 +37,8 @@ unread-emails =
let value = bundle.format_pattern(&pattern, Some(&args), &mut errors);
println!("{}", value);

let mut args = HashMap::new();
args.insert("emailCount".to_string(), FluentValue::into_number("1.0"));
let mut args = FluentArgs::new();
args.insert("emailCount", FluentValue::into_number("1.0"));

let msg = bundle
.get_message("unread-emails")
Expand Down
7 changes: 3 additions & 4 deletions fluent-bundle/examples/selector.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use fluent_bundle::{FluentBundle, FluentResource, FluentValue};
use std::collections::HashMap;
use fluent_bundle::{FluentArgs, FluentBundle, FluentResource, FluentValue};

fn main() {
let ftl_string = String::from(
Expand Down Expand Up @@ -29,8 +28,8 @@ hello-world2 = Hello { $name ->
let value = bundle.format_pattern(&pattern, None, &mut errors);
println!("{}", value);

let mut args = HashMap::new();
args.insert("name".to_string(), FluentValue::from("moon"));
let mut args = FluentArgs::new();
args.insert("name", FluentValue::from("moon"));

let msg = bundle
.get_message("hello-world2")
Expand Down
15 changes: 7 additions & 8 deletions fluent-bundle/examples/simple-app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
//!
//! If the second argument is omitted, `en-US` locale is used as the
//! default one.
use fluent_bundle::{FluentBundle, FluentResource, FluentValue};
use fluent_bundle::{FluentArgs, FluentBundle, FluentResource, FluentValue};
use fluent_locale::{negotiate_languages, NegotiationStrategy};
use std::collections::HashMap;
use std::env;
use std::fs;
use std::fs::File;
Expand Down Expand Up @@ -130,9 +129,9 @@ fn main() {
Ok(i) => {
// 7.2. Construct a map of arguments
// to format the message.
let mut args = HashMap::new();
args.insert("input".to_string(), FluentValue::from(i));
args.insert("value".to_string(), FluentValue::from(collatz(i)));
let mut args = FluentArgs::new();
args.insert("input", FluentValue::from(i));
args.insert("value", FluentValue::from(collatz(i)));
// 7.3. Format the message.
let mut errors = vec![];
let msg = bundle
Expand All @@ -143,9 +142,9 @@ fn main() {
println!("{}", value);
}
Err(err) => {
let mut args = HashMap::new();
args.insert("input".to_string(), FluentValue::from(input.as_str()));
args.insert("reason".to_string(), FluentValue::from(err.to_string()));
let mut args = FluentArgs::new();
args.insert("input", FluentValue::from(input.as_str()));
args.insert("reason", FluentValue::from(err.to_string()));
let mut errors = vec![];
let msg = bundle
.get_message("input-parse-error")
Expand Down
10 changes: 5 additions & 5 deletions fluent-bundle/src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub struct FluentMessage<'m> {
pub attributes: HashMap<&'m str, &'m ast::Pattern<'m>>,
}

pub type FluentArgs<'args> = HashMap<&'args str, FluentValue<'args>>;

/// A collection of localization messages for a single locale, which are meant
/// to be used together in a single view, widget or any other UI abstraction.
///
Expand All @@ -48,7 +50,7 @@ pub struct FluentMessage<'m> {
/// .expect("Failed to add FTL resources to the bundle.");
///
/// let mut args = HashMap::new();
/// args.insert("name".to_string(), FluentValue::from("Rustacean"));
/// args.insert("name", FluentValue::from("Rustacean"));
///
/// let msg = bundle.get_message("intro").expect("Message doesn't exist.");
/// let mut errors = vec![];
Expand Down Expand Up @@ -282,7 +284,7 @@ impl<R> FluentBundle<R> {
pub fn format_pattern<'bundle>(
&'bundle self,
pattern: &'bundle ast::Pattern,
args: Option<&'bundle HashMap<String, FluentValue>>,
args: Option<&'bundle FluentArgs>,
errors: &mut Vec<FluentError>,
) -> Cow<'bundle, str>
where
Expand Down Expand Up @@ -335,9 +337,7 @@ impl<R> FluentBundle<R> {
/// [FTL syntax guide]: https://projectfluent.org/fluent/guide/functions.html
pub fn add_function<F: 'static>(&mut self, id: &str, func: F) -> Result<(), FluentError>
where
F: for<'a> Fn(&[FluentValue<'a>], &HashMap<String, FluentValue<'a>>) -> FluentValue<'a>
+ Sync
+ Send,
F: for<'a> Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Sync + Send,
{
match self.entries.entry(id.to_owned()) {
HashEntry::Vacant(entry) => {
Expand Down
10 changes: 3 additions & 7 deletions fluent-bundle/src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
//! `Entry` is used to store Messages, Terms and Functions in `FluentBundle` instances.
use std::borrow::Borrow;
use std::collections::HashMap;

use fluent_syntax::ast;

use crate::bundle::FluentBundle;
use crate::bundle::{FluentArgs, FluentBundle};
use crate::resource::FluentResource;
use crate::types::FluentValue;

pub type FluentFunction = Box<
dyn for<'a> Fn(&[FluentValue<'a>], &HashMap<String, FluentValue<'a>>) -> FluentValue<'a>
+ Send
+ Sync,
>;
pub type FluentFunction =
Box<dyn for<'a> Fn(&[FluentValue<'a>], &FluentArgs) -> FluentValue<'a> + Send + Sync>;

pub enum Entry {
Message([usize; 2]),
Expand Down
9 changes: 4 additions & 5 deletions fluent-bundle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
//! # Example
//!
//! ```
//! use fluent_bundle::{FluentBundle, FluentValue, FluentResource};
//! use std::collections::HashMap;
//! use fluent_bundle::{FluentBundle, FluentValue, FluentResource, FluentArgs};
//! use unic_langid::langid;
//!
//! let ftl_string = String::from("
Expand All @@ -36,8 +35,8 @@
//!
//! assert_eq!(&value, "Hello, world!");
//!
//! let mut args = HashMap::new();
//! args.insert("name".to_string(), FluentValue::from("John"));
//! let mut args = FluentArgs::new();
//! args.insert("name", FluentValue::from("John"));
//!
//! let msg = bundle.get_message("intro").expect("Message doesn't exist.");
//! let mut errors = vec![];
Expand All @@ -59,6 +58,6 @@ pub mod resolve;
pub mod resource;
pub mod types;

pub use bundle::FluentBundle;
pub use bundle::{FluentArgs, FluentBundle, FluentMessage};
pub use resource::FluentResource;
pub use types::FluentValue;
21 changes: 7 additions & 14 deletions fluent-bundle/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
//! [`FluentBundle`]: ../bundle/struct.FluentBundle.html

use std::borrow::Borrow;
use std::collections::HashMap;
use std::fmt::Write;

use fluent_syntax::ast;
use fluent_syntax::unicode::unescape_unicode;

use crate::bundle::FluentBundle;
use crate::bundle::{FluentArgs, FluentBundle};
use crate::entry::GetEntry;
use crate::resource::FluentResource;
use crate::types::DisplayableNode;
Expand All @@ -31,20 +30,17 @@ pub struct Scope<'bundle, R: Borrow<FluentResource>> {
/// The current `FluentBundle` instance.
pub bundle: &'bundle FluentBundle<R>,
/// The current arguments passed by the developer.
args: Option<&'bundle HashMap<String, FluentValue<'bundle>>>,
args: Option<&'bundle FluentArgs<'bundle>>,
/// Local args
local_args: Option<HashMap<String, FluentValue<'bundle>>>,
local_args: Option<FluentArgs<'bundle>>,
/// Tracks hashes to prevent infinite recursion.
travelled: smallvec::SmallVec<[&'bundle ast::Pattern<'bundle>; 2]>,
/// Track errors accumulated during resolving.
pub errors: Vec<ResolverError>,
}

impl<'bundle, R: Borrow<FluentResource>> Scope<'bundle, R> {
pub fn new(
bundle: &'bundle FluentBundle<R>,
args: Option<&'bundle HashMap<String, FluentValue>>,
) -> Self {
pub fn new(bundle: &'bundle FluentBundle<R>, args: Option<&'bundle FluentArgs>) -> Self {
Scope {
bundle,
args,
Expand Down Expand Up @@ -281,23 +277,20 @@ impl<'source> ResolveValue<'source> for ast::InlineExpression<'source> {
fn get_arguments<'bundle, R>(
scope: &mut Scope<'bundle, R>,
arguments: &'bundle Option<ast::CallArguments<'bundle>>,
) -> (
Vec<FluentValue<'bundle>>,
HashMap<String, FluentValue<'bundle>>,
)
) -> (Vec<FluentValue<'bundle>>, FluentArgs<'bundle>)
where
R: Borrow<FluentResource>,
{
let mut resolved_positional_args = Vec::new();
let mut resolved_named_args = HashMap::new();
let mut resolved_named_args = FluentArgs::new();

if let Some(ast::CallArguments { named, positional }) = arguments {
for expression in positional {
resolved_positional_args.push(expression.resolve(scope));
}

for arg in named {
resolved_named_args.insert(arg.name.name.to_string(), arg.value.resolve(scope));
resolved_named_args.insert(arg.name.name, arg.value.resolve(scope));
}
}

Expand Down
5 changes: 3 additions & 2 deletions fluent-bundle/tests/resolver_fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::iter;
use std::path::Path;
use std::str::FromStr;

use fluent_bundle::bundle::FluentArgs;
use fluent_bundle::errors::FluentError;
use fluent_bundle::resolve::ResolverError;
use fluent_bundle::{FluentBundle as FluentBundleGeneric, FluentResource, FluentValue};
Expand Down Expand Up @@ -264,14 +265,14 @@ fn test_test(test: &Test, defaults: &Option<TestDefaults>, mut scope: Scope) {
))
};

let args: Option<HashMap<String, FluentValue>> = assert.args.as_ref().map(|args| {
let args: Option<FluentArgs> = assert.args.as_ref().map(|args| {
args.iter()
.map(|(k, v)| {
let val = match f64::from_str(v) {
Ok(_) => FluentValue::Number(v.into()),
Err(_) => FluentValue::String(v.into()),
};
(k.to_string(), val)
(k.as_str(), val)
})
.collect()
});
Expand Down
15 changes: 7 additions & 8 deletions fluent-fallback/examples/simple-fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
//! If the second argument is omitted, `en-US` locale is used as the
//! default one.
use elsa::FrozenMap;
use fluent_bundle::{FluentBundle, FluentResource, FluentValue};
use fluent_bundle::{FluentArgs, FluentBundle, FluentResource, FluentValue};
use fluent_fallback::Localization;
use fluent_locale::{negotiate_languages, NegotiationStrategy};
use std::collections::HashMap;
use std::env;
use std::fs;
use std::fs::File;
Expand Down Expand Up @@ -139,17 +138,17 @@ fn main() {
Ok(i) => {
// 7.2. Construct a map of arguments
// to format the message.
let mut args = HashMap::new();
args.insert("input".to_string(), FluentValue::from(i));
args.insert("value".to_string(), FluentValue::from(collatz(i)));
let mut args = FluentArgs::new();
args.insert("input", FluentValue::from(i));
args.insert("value", FluentValue::from(collatz(i)));
// 7.3. Format the message.
let value = loc.format_value("response-msg", Some(&args));
println!("{}", value);
}
Err(err) => {
let mut args = HashMap::new();
args.insert("input".to_string(), FluentValue::from(input.as_str()));
args.insert("reason".to_string(), FluentValue::from(err.to_string()));
let mut args = FluentArgs::new();
args.insert("input", FluentValue::from(input.as_str()));
args.insert("reason", FluentValue::from(err.to_string()));
let value = loc.format_value("input-parse-error-msg", Some(&args));
println!("{}", value);
}
Expand Down
6 changes: 2 additions & 4 deletions fluent-fallback/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use std::borrow::Borrow;
use std::collections::HashMap;

use fluent_bundle::FluentBundle;
use fluent_bundle::FluentResource;
use fluent_bundle::FluentValue;
use fluent_bundle::{FluentArgs, FluentBundle};

use reiterate::Reiterate;

Expand Down Expand Up @@ -45,7 +43,7 @@ impl<'loc, R> Localization<'loc, R> {
self.bundles = Reiterate::new((self.generate_bundles)(&self.resource_ids));
}

pub fn format_value(&mut self, id: &str, args: Option<&HashMap<String, FluentValue>>) -> String
pub fn format_value(&mut self, id: &str, args: Option<&FluentArgs>) -> String
where
R: Borrow<FluentResource>,
{
Expand Down
15 changes: 7 additions & 8 deletions fluent-resmgr/examples/simple-resmgr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
//!
//! If the second argument is omitted, `en-US` locale is used as the
//! default one.
use fluent_bundle::FluentValue;
use fluent_bundle::{FluentArgs, FluentValue};
use fluent_locale::{negotiate_languages, NegotiationStrategy};
use fluent_resmgr::resource_manager::ResourceManager;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::io;
Expand Down Expand Up @@ -94,9 +93,9 @@ fn main() {
Ok(i) => {
// 6.2. Construct a map of arguments
// to format the message.
let mut args = HashMap::new();
args.insert("input".to_string(), FluentValue::from(i));
args.insert("value".to_string(), FluentValue::from(collatz(i)));
let mut args = FluentArgs::new();
args.insert("input", FluentValue::from(i));
args.insert("value", FluentValue::from(collatz(i)));
// 6.3. Format the message.
let mut errors = vec![];
let msg = bundle.get_message("response-msg").expect("Message exists");
Expand All @@ -105,9 +104,9 @@ fn main() {
println!("{}", value);
}
Err(err) => {
let mut args = HashMap::new();
args.insert("input".to_string(), FluentValue::from(input.to_string()));
args.insert("reason".to_string(), FluentValue::from(err.to_string()));
let mut args = FluentArgs::new();
args.insert("input", FluentValue::from(input.to_string()));
args.insert("reason", FluentValue::from(err.to_string()));
let mut errors = vec![];
let msg = bundle
.get_message("input-parse-error-msg")
Expand Down
Loading