Skip to content

Commit

Permalink
Refactor FluentArgs
Browse files Browse the repository at this point in the history
  • Loading branch information
zbraniecki committed Jul 29, 2019
1 parent 239f5a2 commit 03fd391
Show file tree
Hide file tree
Showing 14 changed files with 93 additions and 88 deletions.
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

0 comments on commit 03fd391

Please sign in to comment.