mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
add string/number distinction to generated Rust methods
This commit is contained in:
parent
e4002d7a5e
commit
b5b21edd11
3 changed files with 57 additions and 27 deletions
|
@ -165,9 +165,11 @@ impl From<String> for Variable {
|
|||
| "kilobytes" | "daysStart" | "daysEnd" | "days" | "secs-per-card" | "remaining"
|
||||
| "hourStart" | "hourEnd" | "correct" => VariableKind::Int,
|
||||
"average-seconds" | "cards-per-minute" => VariableKind::Float,
|
||||
"val" | "found" | "expected" | "part" | "percent" | "day" => VariableKind::Any,
|
||||
"val" | "found" | "expected" | "part" | "percent" | "day" | "number" | "up"
|
||||
| "down" | "seconds" | "megs" => VariableKind::Any,
|
||||
term => {
|
||||
if term.ends_with("Count") || term.ends_with("Secs") {
|
||||
let term = term.to_ascii_lowercase();
|
||||
if term.ends_with("count") {
|
||||
VariableKind::Int
|
||||
} else {
|
||||
VariableKind::String
|
||||
|
|
|
@ -7,7 +7,7 @@ use inflections::Inflect;
|
|||
use std::{fmt::Write, fs, path::PathBuf};
|
||||
|
||||
use crate::{
|
||||
extract::{Module, Translation},
|
||||
extract::{Module, Translation, VariableKind},
|
||||
gather::{TranslationsByFile, TranslationsByLang},
|
||||
};
|
||||
|
||||
|
@ -31,9 +31,8 @@ pub fn write_strings(map: &TranslationsByLang, modules: &[Module]) {
|
|||
fn write_methods(modules: &[Module], buf: &mut String) {
|
||||
buf.push_str(
|
||||
r#"
|
||||
use crate::I18n;
|
||||
use crate::tr_args;
|
||||
use fluent::FluentValue;
|
||||
use crate::{I18n,Number};
|
||||
use fluent::{FluentValue, FluentArgs};
|
||||
use std::borrow::Cow;
|
||||
|
||||
impl I18n {
|
||||
|
@ -46,12 +45,15 @@ impl I18n {
|
|||
let doc = translation.text.replace("\n", " ");
|
||||
let in_args;
|
||||
let out_args;
|
||||
let var_build;
|
||||
if translation.variables.is_empty() {
|
||||
in_args = "".to_string();
|
||||
out_args = ", None".to_string();
|
||||
var_build = "".to_string();
|
||||
} else {
|
||||
in_args = build_in_args(translation);
|
||||
out_args = build_out_args(translation);
|
||||
var_build = build_vars(translation);
|
||||
out_args = ", Some(args)".to_string();
|
||||
}
|
||||
|
||||
writeln!(
|
||||
|
@ -60,6 +62,7 @@ impl I18n {
|
|||
/// {doc}
|
||||
#[inline]
|
||||
pub fn {func}<'a>(&'a self{in_args}) -> Cow<'a, str> {{
|
||||
{var_build}
|
||||
self.translate("{key}"{out_args})
|
||||
}}"#,
|
||||
func = func,
|
||||
|
@ -67,6 +70,7 @@ impl I18n {
|
|||
doc = doc,
|
||||
in_args = in_args,
|
||||
out_args = out_args,
|
||||
var_build = var_build,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -75,19 +79,35 @@ impl I18n {
|
|||
buf.push_str("}\n");
|
||||
}
|
||||
|
||||
fn build_out_args(translation: &Translation) -> String {
|
||||
let v: Vec<_> = translation
|
||||
.variables
|
||||
.iter()
|
||||
.map(|var| {
|
||||
format!(
|
||||
r#""{fluent_name}"=>{rust_name}"#,
|
||||
fluent_name = var.name,
|
||||
rust_name = var.name.to_snake_case()
|
||||
fn build_vars(translation: &Translation) -> String {
|
||||
if translation.variables.is_empty() {
|
||||
"let args = None;\n".into()
|
||||
} else {
|
||||
let mut buf = String::from(
|
||||
r#"
|
||||
let mut args = FluentArgs::new();
|
||||
"#,
|
||||
);
|
||||
for v in &translation.variables {
|
||||
let fluent_name = &v.name;
|
||||
let rust_name = v.name.to_snake_case();
|
||||
let trailer = match v.kind {
|
||||
VariableKind::Any => "",
|
||||
VariableKind::Int | VariableKind::Float => ".into()",
|
||||
VariableKind::String => ".into()",
|
||||
};
|
||||
writeln!(
|
||||
buf,
|
||||
r#" args.set("{fluent_name}", {rust_name}{trailer});"#,
|
||||
fluent_name = fluent_name,
|
||||
rust_name = rust_name,
|
||||
trailer = trailer,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
format!(", Some(tr_args![{}])", v.join(", "))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
buf
|
||||
}
|
||||
}
|
||||
|
||||
fn build_in_args(translation: &Translation) -> String {
|
||||
|
@ -95,13 +115,13 @@ fn build_in_args(translation: &Translation) -> String {
|
|||
.variables
|
||||
.iter()
|
||||
.map(|var| {
|
||||
// let kind = match var.kind {
|
||||
// VariableKind::Int => "i64",
|
||||
// VariableKind::Float => "f64",
|
||||
// VariableKind::String => "&str",
|
||||
// VariableKind::Any => "&str",
|
||||
// };
|
||||
let kind = "impl Into<FluentValue<'a>>";
|
||||
let kind = match var.kind {
|
||||
VariableKind::Int => "impl Number",
|
||||
VariableKind::Float => "impl Number",
|
||||
VariableKind::String => "impl Into<String>",
|
||||
// VariableKind::Any => "&str",
|
||||
_ => "impl Into<FluentValue<'a>>",
|
||||
};
|
||||
format!("{}: {}", var.name.to_snake_case(), kind)
|
||||
})
|
||||
.collect();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
mod generated;
|
||||
|
||||
use fluent::{FluentArgs, FluentResource, FluentValue};
|
||||
use fluent::{types::FluentNumber, FluentArgs, FluentResource, FluentValue};
|
||||
use fluent_bundle::bundle::FluentBundle as FluentBundleOrig;
|
||||
use num_format::Locale;
|
||||
use serde::Serialize;
|
||||
|
@ -17,6 +17,14 @@ type FluentBundle<T> = FluentBundleOrig<T, intl_memoizer::concurrent::IntlLangMe
|
|||
|
||||
pub use fluent::fluent_args as tr_args;
|
||||
|
||||
pub trait Number: Into<FluentNumber> {}
|
||||
impl Number for i32 {}
|
||||
impl Number for i64 {}
|
||||
impl Number for u32 {}
|
||||
impl Number for f32 {}
|
||||
impl Number for u64 {}
|
||||
impl Number for usize {}
|
||||
|
||||
fn remapped_lang_name(lang: &LanguageIdentifier) -> &str {
|
||||
let region = match &lang.region {
|
||||
Some(region) => Some(region.as_str()),
|
||||
|
|
Loading…
Reference in a new issue