Skip to content

Commit 6254832

Browse files
authored
Change the resource ids to be a Set rather than a Vec (#277)
2 parents 9e62af6 + 8a819b5 commit 6254832

File tree

9 files changed

+70
-21
lines changed

9 files changed

+70
-21
lines changed

fluent-fallback/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ futures = "0.3"
2424
async-trait = "0.1"
2525
unic-langid = { version = "0.9" }
2626
once_cell = "1.9"
27+
rustc-hash = "1"
2728

2829
[dev-dependencies]
2930
fluent-langneg = "0.13"

fluent-fallback/examples/simple-fallback.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use fluent_fallback::{
2828
};
2929
use fluent_langneg::{negotiate_languages, NegotiationStrategy};
3030

31+
use rustc_hash::FxHashSet;
3132
use unic_langid::{langid, LanguageIdentifier};
3233

3334
/// This helper struct holds the scheme for converting
@@ -111,7 +112,7 @@ fn main() {
111112
let bundles = get_resource_manager();
112113

113114
let loc = Localization::with_env(
114-
L10N_RESOURCES.iter().map(|&res| res.into()).collect(),
115+
L10N_RESOURCES.iter().map(|&res| res.into()),
115116
true,
116117
app_locales,
117118
bundles,
@@ -168,7 +169,7 @@ fn collatz(n: isize) -> isize {
168169
struct BundleIter {
169170
res_path_scheme: String,
170171
locales: <Vec<LanguageIdentifier> as IntoIterator>::IntoIter,
171-
res_ids: Vec<ResourceId>,
172+
res_ids: FxHashSet<ResourceId>,
172173
}
173174

174175
impl Iterator for BundleIter {
@@ -225,7 +226,7 @@ impl BundleGenerator for Bundles {
225226
fn bundles_iter(
226227
&self,
227228
locales: std::vec::IntoIter<LanguageIdentifier>,
228-
res_ids: Vec<ResourceId>,
229+
res_ids: FxHashSet<ResourceId>,
229230
) -> Self::Iter {
230231
BundleIter {
231232
res_path_scheme: self.res_path_scheme.to_string_lossy().to_string(),

fluent-fallback/src/bundles.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
types::{L10nAttribute, L10nKey, L10nMessage, ResourceId},
77
};
88
use fluent_bundle::{FluentArgs, FluentBundle, FluentError};
9+
use rustc_hash::FxHashSet;
910
use std::borrow::Cow;
1011

1112
pub enum BundlesInner<G>
@@ -50,7 +51,7 @@ impl<G> Bundles<G>
5051
where
5152
G: BundleGenerator,
5253
{
53-
pub fn new<P>(sync: bool, res_ids: Vec<ResourceId>, generator: &G, provider: &P) -> Self
54+
pub fn new<P>(sync: bool, res_ids: FxHashSet<ResourceId>, generator: &G, provider: &P) -> Self
5455
where
5556
G: BundleGenerator<LocalesIter = P::Iter>,
5657
P: LocalesProvider,

fluent-fallback/src/generator.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use fluent_bundle::{FluentBundle, FluentError, FluentResource};
22
use futures::Stream;
3+
use rustc_hash::FxHashSet;
34
use std::borrow::Borrow;
45
use unic_langid::LanguageIdentifier;
56

@@ -22,14 +23,18 @@ pub trait BundleGenerator {
2223
type Iter: Iterator<Item = FluentBundleResult<Self::Resource>>;
2324
type Stream: Stream<Item = FluentBundleResult<Self::Resource>>;
2425

25-
fn bundles_iter(&self, _locales: Self::LocalesIter, _res_ids: Vec<ResourceId>) -> Self::Iter {
26+
fn bundles_iter(
27+
&self,
28+
_locales: Self::LocalesIter,
29+
_res_ids: FxHashSet<ResourceId>,
30+
) -> Self::Iter {
2631
unimplemented!();
2732
}
2833

2934
fn bundles_stream(
3035
&self,
3136
_locales: Self::LocalesIter,
32-
_res_ids: Vec<ResourceId>,
37+
_res_ids: FxHashSet<ResourceId>,
3338
) -> Self::Stream {
3439
unimplemented!();
3540
}

fluent-fallback/src/localization.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
types::ResourceId,
66
};
77
use once_cell::sync::OnceCell;
8+
use rustc_hash::FxHashSet;
89
use std::rc::Rc;
910

1011
pub struct Localization<G, P>
@@ -16,21 +17,24 @@ where
1617
generator: G,
1718
provider: P,
1819
sync: bool,
19-
res_ids: Vec<ResourceId>,
20+
res_ids: FxHashSet<ResourceId>,
2021
}
2122

2223
impl<G, P> Localization<G, P>
2324
where
2425
G: BundleGenerator<LocalesIter = P::Iter> + Default,
2526
P: LocalesProvider + Default,
2627
{
27-
pub fn new(res_ids: Vec<ResourceId>, sync: bool) -> Self {
28+
pub fn new<I>(res_ids: I, sync: bool) -> Self
29+
where
30+
I: IntoIterator<Item = ResourceId>,
31+
{
2832
Self {
2933
bundles: OnceCell::new(),
3034
generator: G::default(),
3135
provider: P::default(),
3236
sync,
33-
res_ids,
37+
res_ids: FxHashSet::from_iter(res_ids.into_iter()),
3438
}
3539
}
3640
}
@@ -40,13 +44,16 @@ where
4044
G: BundleGenerator<LocalesIter = P::Iter>,
4145
P: LocalesProvider,
4246
{
43-
pub fn with_env(res_ids: Vec<ResourceId>, sync: bool, provider: P, generator: G) -> Self {
47+
pub fn with_env<I>(res_ids: I, sync: bool, provider: P, generator: G) -> Self
48+
where
49+
I: IntoIterator<Item = ResourceId>,
50+
{
4451
Self {
4552
bundles: OnceCell::new(),
4653
generator,
4754
provider,
4855
sync,
49-
res_ids,
56+
res_ids: FxHashSet::from_iter(res_ids.into_iter()),
5057
}
5158
}
5259

@@ -55,7 +62,7 @@ where
5562
}
5663

5764
pub fn add_resource_id<T: Into<ResourceId>>(&mut self, res_id: T) {
58-
self.res_ids.push(res_id.into());
65+
self.res_ids.insert(res_id.into());
5966
self.on_change();
6067
}
6168

fluent-fallback/src/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub struct L10nMessage<'l> {
2828
pub attributes: Vec<L10nAttribute<'l>>,
2929
}
3030

31-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
31+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3232
pub enum ResourceType {
3333
/// This is a required resource.
3434
///
@@ -53,7 +53,7 @@ pub enum ResourceType {
5353
}
5454

5555
/// A resource identifier for a localization resource.
56-
#[derive(Debug, Clone)]
56+
#[derive(Debug, Clone, Hash)]
5757
pub struct ResourceId {
5858
/// The resource identifier.
5959
pub value: String,

fluent-fallback/tests/localization_test.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use fluent_fallback::{
1111
types::{L10nKey, ResourceId},
1212
Localization, LocalizationError,
1313
};
14+
use rustc_hash::FxHashSet;
1415
use std::cell::RefCell;
1516
use std::rc::Rc;
1617
use unic_langid::{langid, LanguageIdentifier};
@@ -55,7 +56,7 @@ impl LocalesProvider for Locales {
5556
// lack of GATs, these have to own members instead of taking slices.
5657
struct BundleIter {
5758
locales: <Vec<LanguageIdentifier> as IntoIterator>::IntoIter,
58-
res_ids: Vec<ResourceId>,
59+
res_ids: FxHashSet<ResourceId>,
5960
}
6061

6162
impl Iterator for BundleIter {
@@ -132,11 +133,19 @@ impl BundleGenerator for ResourceManager {
132133
type Iter = BundleIter;
133134
type Stream = BundleIter;
134135

135-
fn bundles_iter(&self, locales: Self::LocalesIter, res_ids: Vec<ResourceId>) -> Self::Iter {
136+
fn bundles_iter(
137+
&self,
138+
locales: Self::LocalesIter,
139+
res_ids: FxHashSet<ResourceId>,
140+
) -> Self::Iter {
136141
BundleIter { locales, res_ids }
137142
}
138143

139-
fn bundles_stream(&self, locales: Self::LocalesIter, res_ids: Vec<ResourceId>) -> Self::Stream {
144+
fn bundles_stream(
145+
&self,
146+
locales: Self::LocalesIter,
147+
res_ids: FxHashSet<ResourceId>,
148+
) -> Self::Stream {
140149
BundleIter { locales, res_ids }
141150
}
142151
}
@@ -488,3 +497,22 @@ async fn localization_handle_state_changes_mid_async() {
488497

489498
bundles.format_value("key", None, &mut errors).await;
490499
}
500+
501+
#[test]
502+
fn localization_duplicate_resources() {
503+
let resource_ids: Vec<ResourceId> =
504+
vec!["test.ftl".into(), "test2.ftl".into(), "test2.ftl".into()];
505+
let locales = Locales::new(vec![langid!("pl"), langid!("en-US")]);
506+
let res_mgr = ResourceManager;
507+
let mut errors = vec![];
508+
509+
let loc = Localization::with_env(resource_ids, true, locales, res_mgr);
510+
let bundles = loc.bundles();
511+
512+
let value = bundles
513+
.format_value_sync("hello-world", None, &mut errors)
514+
.unwrap();
515+
assert_eq!(value, Some(Cow::Borrowed("Hello World [pl]")));
516+
517+
assert_eq!(errors.len(), 0, "There were no errors");
518+
}

fluent-resmgr/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ fluent-fallback = { version = "0.6.0", path = "../fluent-fallback" }
2222
unic-langid = "0.9"
2323
elsa = "1.5"
2424
futures = "0.3"
25+
rustc-hash = "1"
2526

2627
[dev-dependencies]
2728
unic-langid = { version = "0.9", features = ["macros"]}

fluent-resmgr/src/resource_manager.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use fluent_fallback::{
55
types::ResourceId,
66
};
77
use futures::stream::Stream;
8+
use rustc_hash::FxHashSet;
89
use std::fs;
910
use std::io;
1011
use std::iter;
@@ -83,7 +84,7 @@ impl ResourceManager {
8384
// lack of GATs, these have to own members instead of taking slices.
8485
pub struct BundleIter {
8586
locales: <Vec<LanguageIdentifier> as IntoIterator>::IntoIter,
86-
res_ids: Vec<ResourceId>,
87+
res_ids: FxHashSet<ResourceId>,
8788
}
8889

8990
impl Iterator for BundleIter {
@@ -94,7 +95,7 @@ impl Iterator for BundleIter {
9495

9596
let mut bundle = FluentBundle::new(vec![locale.clone()]);
9697

97-
for res_id in &self.res_ids {
98+
for res_id in self.res_ids.iter() {
9899
let full_path = format!("./tests/resources/{}/{}", locale, res_id);
99100
let source = fs::read_to_string(full_path).unwrap();
100101
let res = FluentResource::try_new(source).unwrap();
@@ -121,14 +122,18 @@ impl BundleGenerator for ResourceManager {
121122
type Iter = BundleIter;
122123
type Stream = BundleIter;
123124

124-
fn bundles_iter(&self, locales: Self::LocalesIter, res_ids: Vec<ResourceId>) -> Self::Iter {
125+
fn bundles_iter(
126+
&self,
127+
locales: Self::LocalesIter,
128+
res_ids: FxHashSet<ResourceId>,
129+
) -> Self::Iter {
125130
BundleIter { locales, res_ids }
126131
}
127132

128133
fn bundles_stream(
129134
&self,
130135
_locales: Self::LocalesIter,
131-
_res_ids: Vec<ResourceId>,
136+
_res_ids: FxHashSet<ResourceId>,
132137
) -> Self::Stream {
133138
todo!()
134139
}

0 commit comments

Comments
 (0)