Create a little application which manages an l10n messages database #290

Merged
savanni merged 16 commits from l10n-db into main 2025-02-25 06:45:56 +00:00
8 changed files with 69 additions and 19 deletions
Showing only changes of commit 0df0ff9419 - Show all commits

7
Cargo.lock generated
View File

@ -2422,6 +2422,7 @@ dependencies = [
"tempfile",
"thiserror 2.0.11",
"toml",
"xml-rs",
]
[[package]]
@ -5435,6 +5436,12 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "xml-rs"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
[[package]]
name = "yansi-term"
version = "0.1.2"

View File

@ -12,6 +12,7 @@ serde_json = "1.0.139"
tempfile = "3.17.1"
thiserror = "2.0.11"
toml = "0.8.20"
xml-rs = "0.8.25"
# [lib]
# name = "l10n_db"

View File

@ -1 +0,0 @@
{"SaveSettings":"Save Settings","Welcome":"Welcome to FitnessTrax"}

View File

@ -7,7 +7,7 @@ use std::{
use clap::{Parser, Subcommand};
use icu_locid::{langid, LanguageIdentifier};
use l10n_db::{self, export_file, read_file, Bundle, Editor, ReadError};
use l10n_db::{self, js, read_file, xliff, Bundle, Editor, ReadError};
use serde::Deserialize;
#[derive(Parser)]
@ -76,7 +76,12 @@ fn main() {
}
Some(Commands::Export { format, locale }) => {
let locale = locale.as_ref().map(|l| l.clone().parse::<LanguageIdentifier>().unwrap()).unwrap_or(langid!("en"));
export_file(&bundle, locale, &PathBuf::from("output.json")).unwrap();
match format.as_ref() {
"js" => js::export_file(&bundle, locale, &PathBuf::from("output.json")).unwrap(),
"xliff" => xliff::export_file(&bundle, locale, &PathBuf::from("output.xliff")).unwrap(),
_ => todo!(),
}
},
None => {}
}

View File

@ -0,0 +1,4 @@
pub mod js;
pub mod xliff;

View File

@ -0,0 +1,48 @@
use std::{fs::File, io, path::Path};
use icu_locid::LanguageIdentifier;
use xml::{writer::XmlEvent, EmitterConfig, EventWriter};
use crate::{Bundle, Message, WriteError};
pub fn export_file(
bundle: &Bundle,
locale: LanguageIdentifier,
path: &Path,
) -> Result<(), WriteError> {
let mut file = File::create(path).unwrap();
export_fh(bundle, locale, &mut file)
}
pub fn export_fh(
bundle: &Bundle,
locale: LanguageIdentifier,
fh: &mut File,
) -> Result<(), WriteError> {
let output = io::stdout();
let mut writer = EmitterConfig::new()
.perform_indent(true)
.create_writer(output);
writer.write(XmlEvent::start_element("xliff")).unwrap();
writer.write(XmlEvent::start_element("file")).unwrap();
for (key, message) in bundle.message_iter() {
write_message(&mut writer, message, &locale);
}
writer.write(XmlEvent::end_element()).unwrap();
writer.write(XmlEvent::end_element()).unwrap();
Ok(())
}
fn write_message<T>(writer: &mut EventWriter<T>, message: &Message, locale: &LanguageIdentifier)
where
T: std::io::Write,
{
writer.write(XmlEvent::start_element("unit")).unwrap();
writer.write(XmlEvent::start_element("segment")).unwrap();
writer.write(XmlEvent::characters(message.variant(locale).unwrap().content())).unwrap();
writer.write(XmlEvent::end_element()).unwrap();
writer.write(XmlEvent::end_element()).unwrap();
}

View File

@ -4,8 +4,8 @@ pub use bundle::Bundle;
mod editor;
pub use editor::Editor;
mod js_format;
pub use js_format::{export_file, export_fh};
mod formats;
pub use formats::{js, xliff};
mod types;
pub use types::{Message, Variant};
@ -13,17 +13,3 @@ pub use types::{Message, Variant};
mod utils;
pub use utils::*;
/*
#[cfg(test)]
mod test {
#[test]
fn it_can_represent_an_untranslated_message() {
todo!()
}
#[test]
fn it_can_represent_a_partially_translated_message() {
todo!()
}
}
*/