mirror of
https://github.com/ankitects/anki.git
synced 2025-12-12 22:36:55 -05: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"
|
| "kilobytes" | "daysStart" | "daysEnd" | "days" | "secs-per-card" | "remaining"
|
||||||
| "hourStart" | "hourEnd" | "correct" => VariableKind::Int,
|
| "hourStart" | "hourEnd" | "correct" => VariableKind::Int,
|
||||||
"average-seconds" | "cards-per-minute" => VariableKind::Float,
|
"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 => {
|
term => {
|
||||||
if term.ends_with("Count") || term.ends_with("Secs") {
|
let term = term.to_ascii_lowercase();
|
||||||
|
if term.ends_with("count") {
|
||||||
VariableKind::Int
|
VariableKind::Int
|
||||||
} else {
|
} else {
|
||||||
VariableKind::String
|
VariableKind::String
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use inflections::Inflect;
|
||||||
use std::{fmt::Write, fs, path::PathBuf};
|
use std::{fmt::Write, fs, path::PathBuf};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
extract::{Module, Translation},
|
extract::{Module, Translation, VariableKind},
|
||||||
gather::{TranslationsByFile, TranslationsByLang},
|
gather::{TranslationsByFile, TranslationsByLang},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -31,9 +31,8 @@ pub fn write_strings(map: &TranslationsByLang, modules: &[Module]) {
|
||||||
fn write_methods(modules: &[Module], buf: &mut String) {
|
fn write_methods(modules: &[Module], buf: &mut String) {
|
||||||
buf.push_str(
|
buf.push_str(
|
||||||
r#"
|
r#"
|
||||||
use crate::I18n;
|
use crate::{I18n,Number};
|
||||||
use crate::tr_args;
|
use fluent::{FluentValue, FluentArgs};
|
||||||
use fluent::FluentValue;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
impl I18n {
|
impl I18n {
|
||||||
|
|
@ -46,12 +45,15 @@ impl I18n {
|
||||||
let doc = translation.text.replace("\n", " ");
|
let doc = translation.text.replace("\n", " ");
|
||||||
let in_args;
|
let in_args;
|
||||||
let out_args;
|
let out_args;
|
||||||
|
let var_build;
|
||||||
if translation.variables.is_empty() {
|
if translation.variables.is_empty() {
|
||||||
in_args = "".to_string();
|
in_args = "".to_string();
|
||||||
out_args = ", None".to_string();
|
out_args = ", None".to_string();
|
||||||
|
var_build = "".to_string();
|
||||||
} else {
|
} else {
|
||||||
in_args = build_in_args(translation);
|
in_args = build_in_args(translation);
|
||||||
out_args = build_out_args(translation);
|
var_build = build_vars(translation);
|
||||||
|
out_args = ", Some(args)".to_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
|
|
@ -60,6 +62,7 @@ impl I18n {
|
||||||
/// {doc}
|
/// {doc}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn {func}<'a>(&'a self{in_args}) -> Cow<'a, str> {{
|
pub fn {func}<'a>(&'a self{in_args}) -> Cow<'a, str> {{
|
||||||
|
{var_build}
|
||||||
self.translate("{key}"{out_args})
|
self.translate("{key}"{out_args})
|
||||||
}}"#,
|
}}"#,
|
||||||
func = func,
|
func = func,
|
||||||
|
|
@ -67,6 +70,7 @@ impl I18n {
|
||||||
doc = doc,
|
doc = doc,
|
||||||
in_args = in_args,
|
in_args = in_args,
|
||||||
out_args = out_args,
|
out_args = out_args,
|
||||||
|
var_build = var_build,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
@ -75,19 +79,35 @@ impl I18n {
|
||||||
buf.push_str("}\n");
|
buf.push_str("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_out_args(translation: &Translation) -> String {
|
fn build_vars(translation: &Translation) -> String {
|
||||||
let v: Vec<_> = translation
|
if translation.variables.is_empty() {
|
||||||
.variables
|
"let args = None;\n".into()
|
||||||
.iter()
|
} else {
|
||||||
.map(|var| {
|
let mut buf = String::from(
|
||||||
format!(
|
r#"
|
||||||
r#""{fluent_name}"=>{rust_name}"#,
|
let mut args = FluentArgs::new();
|
||||||
fluent_name = var.name,
|
"#,
|
||||||
rust_name = var.name.to_snake_case()
|
);
|
||||||
|
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,
|
||||||
)
|
)
|
||||||
})
|
.unwrap();
|
||||||
.collect();
|
}
|
||||||
format!(", Some(tr_args![{}])", v.join(", "))
|
|
||||||
|
buf
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_in_args(translation: &Translation) -> String {
|
fn build_in_args(translation: &Translation) -> String {
|
||||||
|
|
@ -95,13 +115,13 @@ fn build_in_args(translation: &Translation) -> String {
|
||||||
.variables
|
.variables
|
||||||
.iter()
|
.iter()
|
||||||
.map(|var| {
|
.map(|var| {
|
||||||
// let kind = match var.kind {
|
let kind = match var.kind {
|
||||||
// VariableKind::Int => "i64",
|
VariableKind::Int => "impl Number",
|
||||||
// VariableKind::Float => "f64",
|
VariableKind::Float => "impl Number",
|
||||||
// VariableKind::String => "&str",
|
VariableKind::String => "impl Into<String>",
|
||||||
// VariableKind::Any => "&str",
|
// VariableKind::Any => "&str",
|
||||||
// };
|
_ => "impl Into<FluentValue<'a>>",
|
||||||
let kind = "impl Into<FluentValue<'a>>";
|
};
|
||||||
format!("{}: {}", var.name.to_snake_case(), kind)
|
format!("{}: {}", var.name.to_snake_case(), kind)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
mod generated;
|
mod generated;
|
||||||
|
|
||||||
use fluent::{FluentArgs, FluentResource, FluentValue};
|
use fluent::{types::FluentNumber, FluentArgs, FluentResource, FluentValue};
|
||||||
use fluent_bundle::bundle::FluentBundle as FluentBundleOrig;
|
use fluent_bundle::bundle::FluentBundle as FluentBundleOrig;
|
||||||
use num_format::Locale;
|
use num_format::Locale;
|
||||||
use serde::Serialize;
|
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 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 {
|
fn remapped_lang_name(lang: &LanguageIdentifier) -> &str {
|
||||||
let region = match &lang.region {
|
let region = match &lang.region {
|
||||||
Some(region) => Some(region.as_str()),
|
Some(region) => Some(region.as_str()),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue