Implement most of the fluent localisation system
This commit is contained in:
parent
0370de40a1
commit
475f9bc55e
|
@ -40,6 +40,18 @@ pub enum Value {
|
||||||
Reflective(Box<dyn Reflect>),
|
Reflective(Box<dyn Reflect>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Value {
|
||||||
|
pub fn get_type_name(&self) -> String {
|
||||||
|
String::from(match self {
|
||||||
|
Value::Str(_) => "Str",
|
||||||
|
Value::Int(_) => "Int",
|
||||||
|
Value::Bool(_) => "Bool",
|
||||||
|
Value::List(_) => "List",
|
||||||
|
Value::Reflective(reflective) => reflective.type_name(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref U8_TYPEID: TypeId = TypeId::of::<u8>();
|
static ref U8_TYPEID: TypeId = TypeId::of::<u8>();
|
||||||
static ref U16_TYPEID: TypeId = TypeId::of::<u16>();
|
static ref U16_TYPEID: TypeId = TypeId::of::<u16>();
|
||||||
|
|
|
@ -4,19 +4,81 @@
|
||||||
|
|
||||||
use crate::engine::Value;
|
use crate::engine::Value;
|
||||||
use crate::interface::LocalisationSystem;
|
use crate::interface::LocalisationSystem;
|
||||||
|
use fluent_templates::fluent_bundle::types::FluentNumber;
|
||||||
|
use fluent_templates::fluent_bundle::FluentValue;
|
||||||
|
use fluent_templates::loader::langid;
|
||||||
|
use fluent_templates::{ArcLoader, LanguageIdentifier, Loader};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
|
|
||||||
pub struct FluentLocalisationSystem {}
|
use thiserror::Error;
|
||||||
|
|
||||||
|
fn interpreter_value_to_fluent_value(v: &Value) -> Option<FluentValue> {
|
||||||
|
match v {
|
||||||
|
Value::Str(str) => Some(FluentValue::String(Cow::Borrowed(&str))),
|
||||||
|
Value::Int(int) => {
|
||||||
|
// This is an unstyled number
|
||||||
|
// TODO Support fancier numbers
|
||||||
|
Some(FluentValue::Number(FluentNumber::from(int)))
|
||||||
|
}
|
||||||
|
Value::Bool(_) => {
|
||||||
|
// TODO I can't believe there's no way to expose this to fluent!
|
||||||
|
None
|
||||||
|
}
|
||||||
|
Value::List(_) => None,
|
||||||
|
Value::Reflective(_) => None,
|
||||||
|
}
|
||||||
|
// TODO It might be good to support a `struct` type here with fancier numbers
|
||||||
|
// or to support FluentNumber types directly, then expose functions to Hornbeam
|
||||||
|
// templates to create them?
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FluentLocalisationSystem {
|
||||||
|
pub fluent: ArcLoader,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FluentLocalisationSystem {}
|
||||||
|
|
||||||
|
#[derive(Error, Clone, Debug)]
|
||||||
|
pub enum FluentLocalisationError {
|
||||||
|
#[error("no translation found for {trans_key} in {lang_id}")]
|
||||||
|
NoTranslation { trans_key: String, lang_id: String },
|
||||||
|
|
||||||
|
#[error("can't convert param {param_name} of type {param_type} to a fluent type")]
|
||||||
|
IncompatibleValue {
|
||||||
|
param_name: String,
|
||||||
|
param_type: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
impl LocalisationSystem for FluentLocalisationSystem {
|
impl LocalisationSystem for FluentLocalisationSystem {
|
||||||
type Error = ();
|
type Error = FluentLocalisationError;
|
||||||
|
|
||||||
fn lookup(
|
fn lookup(
|
||||||
&self,
|
&self,
|
||||||
trans_key: &str,
|
trans_key: &str,
|
||||||
params: &BTreeMap<&str, Value>,
|
params: &BTreeMap<&str, Value>,
|
||||||
) -> Result<Cow<str>, Self::Error> {
|
) -> Result<Cow<str>, Self::Error> {
|
||||||
todo!()
|
let li: LanguageIdentifier = langid!("en-GB"); // TODO get the language tag from somewhere
|
||||||
|
let mut mapped_params = HashMap::with_capacity(params.len());
|
||||||
|
for (&k, v) in params {
|
||||||
|
if let Some(mapped_val) = interpreter_value_to_fluent_value(v) {
|
||||||
|
mapped_params.insert(k, mapped_val);
|
||||||
|
} else {
|
||||||
|
return Err(FluentLocalisationError::IncompatibleValue {
|
||||||
|
param_name: String::from(k),
|
||||||
|
param_type: v.get_type_name(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
match self.fluent.lookup_with_args(&li, trans_key, &mapped_params) {
|
||||||
|
Some(val) => Ok(Cow::Owned(val)),
|
||||||
|
None => {
|
||||||
|
return Err(FluentLocalisationError::NoTranslation {
|
||||||
|
trans_key: String::from(trans_key),
|
||||||
|
lang_id: li.to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue