write methods into generated.rs

This commit is contained in:
Damien Elmes 2021-03-26 23:07:18 +10:00
parent cca1d29cc8
commit 5abc48932c
3 changed files with 93 additions and 8 deletions

View file

@ -23,12 +23,12 @@ pub struct Translation {
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Serialize)]
pub struct Variable {
name: String,
kind: VariableKind,
pub name: String,
pub kind: VariableKind,
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Serialize)]
enum VariableKind {
pub enum VariableKind {
Int,
Float,
String,

View file

@ -7,7 +7,7 @@ use inflections::Inflect;
use std::{fmt::Write, fs, path::PathBuf};
use crate::{
extract::Module,
extract::{Module, Translation, VariableKind},
gather::{TranslationsByFile, TranslationsByLang},
};
@ -21,12 +21,100 @@ pub fn write_strings(map: &TranslationsByLang, modules: &[Module]) {
// ordered list of translations by module
write_translation_key_index(modules, &mut buf);
write_legacy_tr_enum(modules, &mut buf);
// methods to generate messages
write_methods(modules, &mut buf);
let dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let path = dir.join("strings.rs");
fs::write(&path, buf).unwrap();
}
fn write_methods(modules: &[Module], buf: &mut String) {
buf.push_str(
r#"
use crate::I18n;
use crate::tr_args;
use std::borrow::Cow;
impl I18n {
"#,
);
for module in modules {
for translation in &module.translations {
let func = translation.key.to_snake_case();
let key = &translation.key;
let doc = translation.text.replace("\n", " ");
let in_args;
let out_args;
let outtype;
let trailer;
if translation.variables.is_empty() {
in_args = "".to_string();
out_args = ", None".to_string();
outtype = "Cow<'a, str>";
trailer = "";
} else {
in_args = build_in_args(translation);
out_args = build_out_args(translation);
outtype = "String";
trailer = ".to_string()";
}
writeln!(
buf,
r#"
/// {doc}
#[inline]
pub fn {func}<'a>(&'a self{in_args}) -> {outtype} {{
self.tr_("{key}"{out_args}){trailer}
}}"#,
func = func,
key = key,
doc = doc,
outtype = outtype,
in_args = in_args,
out_args = out_args,
trailer = trailer,
)
.unwrap();
}
}
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()
)
})
.collect();
format!(", Some(tr_args![{}])", v.join(", "))
}
fn build_in_args(translation: &Translation) -> String {
let v: Vec<_> = translation
.variables
.iter()
.map(|var| {
let kind = match var.kind {
VariableKind::Int => "i64",
VariableKind::Float => "f64",
VariableKind::String => "&str",
VariableKind::Any => "&str",
};
format!("{}: {}", var.name.to_snake_case(), kind)
})
.collect();
format!(", {}", v.join(", "))
}
fn write_legacy_tr_enum(modules: &[Module], buf: &mut String) {
buf.push_str("pub enum LegacyKey {\n");
for module in modules {

View file

@ -129,10 +129,7 @@ impl Collection {
fn card_stats_to_string(&mut self, cs: CardStats) -> Result<String> {
let i18n = &self.i18n;
let mut stats = vec![(
i18n.tr(TR::CardStatsAdded).to_string(),
cs.added.date_string(),
)];
let mut stats = vec![(i18n.card_stats_added().into(), cs.added.date_string())];
if let Some(first) = cs.first_review {
stats.push((
i18n.tr(TR::CardStatsFirstReview).into(),