Create a little application which manages an l10n messages database #290
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -2422,6 +2422,7 @@ dependencies = [
|
|||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.11",
|
"thiserror 2.0.11",
|
||||||
"toml",
|
"toml",
|
||||||
|
"xml-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5435,6 +5436,12 @@ version = "0.5.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xml-rs"
|
||||||
|
version = "0.8.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yansi-term"
|
name = "yansi-term"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -12,6 +12,7 @@ serde_json = "1.0.139"
|
|||||||
tempfile = "3.17.1"
|
tempfile = "3.17.1"
|
||||||
thiserror = "2.0.11"
|
thiserror = "2.0.11"
|
||||||
toml = "0.8.20"
|
toml = "0.8.20"
|
||||||
|
xml-rs = "0.8.25"
|
||||||
|
|
||||||
# [lib]
|
# [lib]
|
||||||
# name = "l10n_db"
|
# name = "l10n_db"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
{"SaveSettings":"Save Settings","Welcome":"Welcome to FitnessTrax"}
|
|
@ -7,7 +7,7 @@ use std::{
|
|||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
use icu_locid::{langid, LanguageIdentifier};
|
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;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@ -76,7 +76,12 @@ fn main() {
|
|||||||
}
|
}
|
||||||
Some(Commands::Export { format, locale }) => {
|
Some(Commands::Export { format, locale }) => {
|
||||||
let locale = locale.as_ref().map(|l| l.clone().parse::<LanguageIdentifier>().unwrap()).unwrap_or(langid!("en"));
|
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 => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
4
l10n-db/src/formats/mod.rs
Normal file
4
l10n-db/src/formats/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod js;
|
||||||
|
pub mod xliff;
|
||||||
|
|
||||||
|
|
48
l10n-db/src/formats/xliff.rs
Normal file
48
l10n-db/src/formats/xliff.rs
Normal 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();
|
||||||
|
}
|
@ -4,8 +4,8 @@ pub use bundle::Bundle;
|
|||||||
mod editor;
|
mod editor;
|
||||||
pub use editor::Editor;
|
pub use editor::Editor;
|
||||||
|
|
||||||
mod js_format;
|
mod formats;
|
||||||
pub use js_format::{export_file, export_fh};
|
pub use formats::{js, xliff};
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
pub use types::{Message, Variant};
|
pub use types::{Message, Variant};
|
||||||
@ -13,17 +13,3 @@ pub use types::{Message, Variant};
|
|||||||
mod utils;
|
mod utils;
|
||||||
pub use 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!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user