Skip to content

Commit 145bcd5

Browse files
committed
Remove bundle list
One FluentBundle can contain multiple FluentResources which are FTL files. Fixes #40
1 parent 9fa068a commit 145bcd5

File tree

1 file changed

+44
-25
lines changed

1 file changed

+44
-25
lines changed

rust/src/fluent/translation.rs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use std::borrow::Cow;
2-
use std::sync::{Arc, RwLock};
3-
42
use fluent::types::{FluentNumber, FluentNumberOptions};
53
use fluent::{FluentArgs, FluentBundle, FluentError, FluentResource, FluentValue};
64
use godot::prelude::*;
@@ -19,7 +17,7 @@ pub struct TranslationFluent {
1917
#[var(get = get_message_pattern, set = set_message_pattern)]
2018
message_pattern: GString,
2119
message_pattern_regex: Option<Gd<RegEx>>,
22-
bundles: Arc<RwLock<Vec<FluentBundle<FluentResource>>>>,
20+
bundle: Option<FluentBundle<FluentResource>>,
2321
base: Base<Translation>,
2422
}
2523

@@ -35,7 +33,7 @@ impl ITranslation for TranslationFluent {
3533
Self {
3634
message_pattern: GString::new(),
3735
message_pattern_regex: None,
38-
bundles: Arc::new(RwLock::new(Vec::new())),
36+
bundle: None,
3937
base,
4038
}
4139
}
@@ -89,15 +87,7 @@ impl TranslationFluent {
8987
}
9088
}
9189

92-
let bundles = self.bundles.read().unwrap();
93-
94-
let result = bundles
95-
.iter()
96-
.filter_map(|bundle| {
97-
Self::translate(bundle, &msg, &args.clone(), if context.is_empty() { None } else { Some(&context) })
98-
})
99-
.next();
100-
90+
let result = self.translate(&msg, &args.clone(), if context.is_empty() { None } else { Some(&context) });
10191
match result {
10292
Some(text) => StringName::from(text),
10393
None => StringName::default(),
@@ -180,7 +170,13 @@ impl TranslationFluent {
180170
output
181171
}
182172

183-
pub fn translate(bundle: &FluentBundle<FluentResource>, message_id: &StringName, args: &Dictionary, attribute: Option<&StringName>) -> Option<String> {
173+
pub fn translate(&self, message_id: &StringName, args: &Dictionary, attribute: Option<&StringName>) -> Option<String> {
174+
if self.bundle.is_none() {
175+
godot_error!("Unable to translate before adding at least one FTL file to translation.");
176+
return None;
177+
}
178+
179+
let bundle = self.bundle.as_ref().unwrap();
184180
let message = bundle.get_message(&String::from(message_id));
185181
message.as_ref()?;
186182
let message = message.unwrap();
@@ -238,22 +234,49 @@ impl TranslationFluent {
238234

239235
#[func]
240236
pub fn add_bundle_from_text(&mut self, text: String) -> GdErr {
237+
let bundle = match &mut self.bundle {
238+
Some(bundle) => bundle,
239+
None => &mut {
240+
let bundle = self.create_bundle();
241+
match bundle {
242+
Ok(bundle) => {
243+
self.bundle = Some(bundle);
244+
self.bundle.as_mut().unwrap()
245+
},
246+
Err(err) => return err
247+
}
248+
},
249+
};
250+
241251
let res = FluentResource::try_new(text);
242252
if res.is_err() {
243253
// TODO: I could give more parser error details here, and probably should? :)
244254
return GdErr::ERR_PARSE_ERROR;
245255
}
256+
let res = res.unwrap();
257+
258+
Self::map_fluent_error(&bundle.add_resource(res))
259+
}
260+
261+
fn create_bundle(&self) -> Result<FluentBundle<FluentResource>, GdErr> {
262+
let mut bundle = FluentBundle::new(self.get_fluent_locales()?);
263+
let project_settings = ProjectSettings::singleton();
264+
bundle.set_use_isolating(bool::from_variant(&project_settings.get_setting(PROJECT_SETTING_UNICODE_ISOLATION.into())));
265+
Ok(bundle)
266+
}
267+
268+
// TODO: Listen to NOTIFICATION_TRANSLATION_CHANGED on MainLoop. On notification, update the existing bundle's "locales" field.
269+
fn get_fluent_locales(&self) -> Result<Vec<LanguageIdentifier>, GdErr> {
246270
let lang = self.base().get_locale();
247271
if lang.is_empty() {
248272
// Give a user-friendly message.
249-
godot_error!("Failed to add bundle to TranslationFluent: locale has not been set.");
250-
return GdErr::ERR_DOES_NOT_EXIST;
273+
godot_error!("Failed to create bundle for TranslationFluent: locale has not been set.");
274+
return Err(GdErr::ERR_DOES_NOT_EXIST);
251275
}
252-
let res = res.unwrap();
253-
let mut bundles = self.bundles.write().unwrap();
276+
254277
let lang_id = String::from(lang).parse::<LanguageIdentifier>();
255278
match lang_id {
256-
Err(err) => Self::map_langid_error(err),
279+
Err(err) => Err(Self::map_langid_error(err)),
257280
Ok(lang_id) => {
258281
let project_settings = ProjectSettings::singleton();
259282
let mut locales = vec![lang_id];
@@ -262,17 +285,13 @@ impl TranslationFluent {
262285
if fallback_locale.len() >= 2 {
263286
let fallback_locale_id = fallback_locale.to_string().parse::<LanguageIdentifier>();
264287
match fallback_locale_id {
265-
Err(err) => return Self::map_langid_error(err),
288+
Err(err) => return Err(Self::map_langid_error(err)),
266289
Ok(fallback_locale_id) => {
267290
locales.push(fallback_locale_id);
268291
}
269292
}
270293
}
271-
let mut bundle = FluentBundle::new(locales);
272-
bundle.set_use_isolating(bool::from_variant(&project_settings.get_setting(PROJECT_SETTING_UNICODE_ISOLATION.into())));
273-
let err = Self::map_fluent_error(&bundle.add_resource(res));
274-
bundles.push(bundle);
275-
err
294+
Ok(locales)
276295
}
277296
}
278297
}

0 commit comments

Comments
 (0)