Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3d69f32
Initial attempt to write a zero-copy parser
Jul 29, 2018
77c2b38
Migrate resolver to use copy-free parser
Oct 29, 2018
bdbdaad
Switch to elsa
Dec 28, 2018
6e02272
Merge fluent-bundle and fluent and attempt to use ResourceManager via…
Jan 1, 2019
652b623
Revert "Merge fluent-bundle and fluent and attempt to use ResourceMan…
Jan 1, 2019
9a9c3ab
Drop FluentBundle::add_messages
Jan 1, 2019
957942e
Convert simple-app example to use add_resource
Jan 2, 2019
377ea56
Switch to use rental crate to store source string on FluentResource
Jan 5, 2019
d50fc3e
Fix benches for fluent-bundle
Jan 5, 2019
e26dd25
Fix the crate for stable rust
Jan 5, 2019
bbac435
Use annotate-snippets 0.5
Jan 5, 2019
bc57ec6
Use newer serde to simplify the json ast serialization
Jan 7, 2019
2242b29
Add docs for FluentBundle
JohnHeitmann Dec 12, 2018
bf6a75e
Anonymized example. Tiny style tweak.
JohnHeitmann Dec 12, 2018
bd74a4a
Corrected error description for FluentBundle.format
JohnHeitmann Dec 12, 2018
b9f0886
More clarification on the various flavors of format error.
JohnHeitmann Dec 13, 2018
c555be5
Merge fixes
JohnHeitmann Jan 7, 2019
7aef4d1
Minor cleanups in the parser
Jan 7, 2019
5191b37
Speed up the parser by reducing the Pattern logic
Jan 7, 2019
37201d9
Improve FluentBundle docs
JohnHeitmann Jan 8, 2019
bd3319d
A bunch of small cleanups to prepare for fuzzer
Jan 8, 2019
7941054
Move ast::Variant::value to be a Pattern
Jan 8, 2019
8a64bbe
Add a note explaining the deviation from the EBNF
Jan 8, 2019
fb569af
Remove the unnecessary externs
Jan 8, 2019
a2fa843
Improve get_number_literal to report errors on broken numbers
Jan 8, 2019
d629ae2
Various small perf optimizations and pointer overflow prevention
Jan 9, 2019
aebb85d
Some more parser cleanups.
Jan 9, 2019
7361dbc
Merge branch 'copy-free-resolver' into docs
JohnHeitmann Jan 10, 2019
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target/
*/target/
**/*.rs.bk
Cargo.lock
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[workspace]
members = [
"fluent-syntax",
"fluent-bundle",
"fluent-cli",
"fluent",
"fluent-syntax"
]
File renamed without changes.
26 changes: 26 additions & 0 deletions fluent-bundle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "fluent-bundle"
description = """
A localization system designed to unleash the entire expressive power of
natural language translations.
"""
version = "0.4.3"
edition = "2018"
authors = [
"Zibi Braniecki <[email protected]>",
"Staś Małolepszy <[email protected]>"
]
homepage = "http://www.projectfluent.org"
license = "Apache-2.0/MIT"
repository = "https://github.com/projectfluent/fluent-rs"
readme = "README.md"
keywords = ["localization", "l10n", "i18n", "intl", "internationalization"]
categories = ["localization", "internationalization"]

[dependencies]
fluent-locale = "^0.4.1"
fluent-syntax = { path = "../fluent-syntax" }
failure = "^0.1"
failure_derive = "^0.1"
intl_pluralrules = "^1.0"
rental = "^0.5.2"
2 changes: 1 addition & 1 deletion fluent/README.md → fluent-bundle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Usage
-----

```rust
use fluent::bundle::FluentBundle;
use fluent_bundle::FluentBundle;

fn main() {
let mut bundle = FluentBundle::new(&["en-US"]);
Expand Down
39 changes: 23 additions & 16 deletions fluent/benches/lib.rs → fluent-bundle/benches/lib.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,70 @@
#![feature(test)]

extern crate fluent;
extern crate fluent_syntax;
extern crate test;

use fluent::bundle::FluentBundle;
use fluent_syntax::{ast, parser::parse};
use fluent_bundle::bundle::FluentBundle;
use fluent_bundle::resource::FluentResource;
use fluent_syntax::ast;
use std::fs::File;
use std::io;
use std::io::Read;
use test::Bencher;

fn read_file(path: &str) -> Result<String, io::Error> {
let mut f = try!(File::open(path));
let mut f = File::open(path)?;
let mut s = String::new();
try!(f.read_to_string(&mut s));
f.read_to_string(&mut s)?;
Ok(s)
}

#[bench]
fn bench_simple_format(b: &mut Bencher) {
let source = read_file("./benches/simple.ftl").expect("Couldn't load file");
let resource = parse(&source).unwrap();
let res = FluentResource::try_new(source).expect("Couldn't parse an FTL source");

let mut ids = Vec::new();

for entry in resource.body {
for entry in &res.ast().body {
match entry {
ast::Entry::Message(ast::Message { id, .. }) => ids.push(id.name),
ast::ResourceEntry::Entry(ast::Entry::Message(ast::Message { id, .. })) => {
ids.push(id.name)
}
_ => continue,
};
}

let mut bundle = FluentBundle::new(&["x-testing"]);
bundle.add_messages(&source).unwrap();
bundle
.add_resource(&res)
.expect("Couldn't add FluentResource to the FluentBundle");

b.iter(|| {
for id in &ids {
bundle.format(id.as_str(), None);
bundle.format(id, None);
}
});
}

#[bench]
fn bench_menubar_format(b: &mut Bencher) {
let source = read_file("./benches/menubar.ftl").expect("Couldn't load file");
let resource = parse(&source).unwrap();
let res = FluentResource::try_new(source).expect("Couldn't parse an FTL source");

let mut ids = Vec::new();

for entry in resource.body {
for entry in &res.ast().body {
match entry {
ast::Entry::Message(ast::Message { id, .. }) => ids.push(id.name),
ast::ResourceEntry::Entry(ast::Entry::Message(ast::Message { id, .. })) => {
ids.push(id.name)
}
_ => continue,
};
}

let mut bundle = FluentBundle::new(&["x-testing"]);
bundle.add_messages(&source).unwrap();
bundle
.add_resource(&res)
.expect("Couldn't add FluentResource to the FluentBundle");

b.iter(|| {
for id in &ids {
Expand All @@ -66,7 +73,7 @@ fn bench_menubar_format(b: &mut Bencher) {
// widgets may only expect attributes and they shouldn't be forced to display a value.
// Here however it doesn't matter because we know for certain that the message for `id`
// exists.
bundle.format_message(id.as_str(), None);
bundle.format_message(id, None);
}
});
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
extern crate fluent;

use fluent::bundle::FluentBundle;
use fluent::types::FluentValue;
use fluent_bundle::bundle::FluentBundle;
use fluent_bundle::resource::FluentResource;
use fluent_bundle::types::FluentValue;
use std::collections::HashMap;

fn main() {
let mut bundle = FluentBundle::new(&["en"]);
bundle
.add_messages(
"
let res = FluentResource::try_new(
"
hello-world = Hello { $name }
ref = The previous message says { hello-world }
unread-emails =
{ $emailCount ->
[one] You have { $emailCount } unread email
*[other] You have { $emailCount } unread emails
}
",
)
.unwrap();
"
.to_owned(),
)
.unwrap();
let mut bundle = FluentBundle::new(&["en"]);
bundle.add_resource(&res).unwrap();

let mut args = HashMap::new();
args.insert("name", FluentValue::from("John"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
extern crate fluent;

use fluent::bundle::FluentBundle;
use fluent::types::FluentValue;
use fluent_bundle::bundle::FluentBundle;
use fluent_bundle::resource::FluentResource;
use fluent_bundle::types::FluentValue;

fn main() {
// We define the resources here so that they outlive
// the bundle.
let res1 = FluentResource::try_new("hello-world = Hey there! { HELLO() }".to_owned()).unwrap();
let res2 =
FluentResource::try_new("meaning-of-life = { MEANING_OF_LIFE(42) }".to_owned()).unwrap();
let res3 = FluentResource::try_new(
"all-your-base = { BASE_OWNERSHIP(hello, ownership: \"us\") }".to_owned(),
)
.unwrap();

let mut bundle = FluentBundle::new(&["en-US"]);

// Test for a simple function that returns a string
Expand Down Expand Up @@ -40,15 +49,9 @@ fn main() {
})
.unwrap();

bundle
.add_messages("hello-world = Hey there! { HELLO() }")
.unwrap();
bundle
.add_messages("meaning-of-life = { MEANING_OF_LIFE(42) }")
.unwrap();
bundle
.add_messages("all-your-base = { BASE_OWNERSHIP(hello, ownership: \"us\") }")
.unwrap();
bundle.add_resource(&res1).unwrap();
bundle.add_resource(&res2).unwrap();
bundle.add_resource(&res3).unwrap();

let value = bundle.format("hello-world", None);
assert_eq!(
Expand Down
10 changes: 10 additions & 0 deletions fluent-bundle/examples/hello.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use fluent_bundle::bundle::FluentBundle;
use fluent_bundle::resource::FluentResource;

fn main() {
let res = FluentResource::try_new("hello-world = Hello, world!".to_owned()).unwrap();
let mut bundle = FluentBundle::new(&["en-US"]);
bundle.add_resource(&res).unwrap();
let (value, _) = bundle.format("hello-world", None).unwrap();
assert_eq!(&value, "Hello, world!");
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
extern crate fluent;

use fluent::bundle::FluentBundle;
use fluent_bundle::bundle::FluentBundle;
use fluent_bundle::resource::FluentResource;

fn main() {
let mut bundle = FluentBundle::new(&["x-testing"]);
bundle
.add_messages(
"
let res = FluentResource::try_new(
"
foo = Foo
foobar = { foo } Bar
bazbar = { baz } Bar
",
)
.unwrap();
"
.to_owned(),
)
.unwrap();

let mut bundle = FluentBundle::new(&["x-testing"]);
bundle.add_resource(&res).unwrap();

match bundle.format("foobar", None) {
Some((value, _)) => println!("{}", value),
Expand Down
7 changes: 7 additions & 0 deletions fluent-bundle/examples/resources/en-US/simple.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
missing-arg-error = Error: Please provide a number as argument.
input-parse-error = Error: Could not parse input `{ $input }`. Reason: { $reason }
response-msg =
{ $value ->
[one] "{ $input }" has one Collatz step.
*[other] "{ $input }" has { $value } Collatz steps.
}
8 changes: 8 additions & 0 deletions fluent-bundle/examples/resources/pl/simple.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
missing-arg-error = Błąd: Proszę wprowadzić liczbę jako argument.
input-parse-error = Błąd: Nie udało się sparsować `{ $input }`. Powód: { $reason }
response-msg =
{ $value ->
[one] "{ $input }" ma jeden krok Collatza.
[few] "{ $input }" ma { $value } kroki Collatza.
*[many] "{ $input }" ma { $value } kroków Collatza.
}
22 changes: 11 additions & 11 deletions fluent/examples/selector.rs → fluent-bundle/examples/selector.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
extern crate fluent;

use fluent::bundle::FluentBundle;
use fluent::types::FluentValue;
use fluent_bundle::bundle::FluentBundle;
use fluent_bundle::resource::FluentResource;
use fluent_bundle::types::FluentValue;
use std::collections::HashMap;

fn main() {
let mut bundle = FluentBundle::new(&["x-testing"]);
bundle
.add_messages(
"
let res = FluentResource::try_new(
"
hello-world = Hello {
*[one] World
[two] Moon
Expand All @@ -18,9 +15,12 @@ hello-world2 = Hello { $name ->
*[world] World
[moon] Moon
}
",
)
.unwrap();
"
.to_owned(),
)
.unwrap();
let mut bundle = FluentBundle::new(&["x-testing"]);
bundle.add_resource(&res).unwrap();

match bundle.format("hello-world", None) {
Some((value, _)) => println!("{}", value),
Expand Down
Loading