Create a little application which manages an l10n messages database #290
@ -1,6 +1,8 @@
|
|||||||
use std::{collections::HashMap, fs::File, io::Write, path::PathBuf};
|
use std::{collections::HashMap, fs::File, io::{BufReader, Read, Write}, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use crate::{Message, WriteError};
|
use chrono::{DateTime, Utc};
|
||||||
|
use icu_locid::LanguageIdentifier;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub struct Bundle {
|
pub struct Bundle {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
@ -48,5 +50,94 @@ fn save_file(path: &PathBuf, s: &[u8]) {
|
|||||||
f.write(s).unwrap();
|
f.write(s).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Message {
|
||||||
|
key: String,
|
||||||
|
description: String,
|
||||||
|
variants: HashMap<LanguageIdentifier, Variant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Message {
|
||||||
|
pub fn new(key: String) -> Self {
|
||||||
|
Self {
|
||||||
|
key,
|
||||||
|
description: "".to_owned(),
|
||||||
|
variants: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_file(path: &Path) -> Message {
|
||||||
|
let file = std::fs::File::open(path).unwrap();
|
||||||
|
let mut content = Vec::new();
|
||||||
|
let mut reader = BufReader::new(file);
|
||||||
|
let _ = reader.read_to_end(&mut content);
|
||||||
|
toml::from_str(&String::from_utf8(content).unwrap()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_description(&mut self, desc: String) {
|
||||||
|
self.description = desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> &str {
|
||||||
|
&self.description
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variant(&self, locale: &LanguageIdentifier) -> Option<&Variant> {
|
||||||
|
self.variants.get(locale)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variant_mut(&mut self, locale: LanguageIdentifier) -> &mut Variant {
|
||||||
|
self.variants.entry(locale.clone()).or_insert(Variant {
|
||||||
|
locale,
|
||||||
|
content: "".to_owned(),
|
||||||
|
modified: Utc::now(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn variants_out_of_date(
|
||||||
|
&self,
|
||||||
|
base_locale: &LanguageIdentifier,
|
||||||
|
) -> Vec<LanguageIdentifier> {
|
||||||
|
match self
|
||||||
|
.variants
|
||||||
|
.get(base_locale)
|
||||||
|
.map(|variant| variant.modified())
|
||||||
|
{
|
||||||
|
Some(base_date) => self
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, value)| base_date > value.modified())
|
||||||
|
.map(|(locale, _)| locale.clone())
|
||||||
|
.collect(),
|
||||||
|
None => vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn missing_variants(&self, locals: Vec<LanguageIdentifier>) -> Vec<LanguageIdentifier> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
|
pub struct Variant {
|
||||||
|
locale: LanguageIdentifier,
|
||||||
|
content: String,
|
||||||
|
modified: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Variant {
|
||||||
|
pub fn content(&self) -> &str {
|
||||||
|
&self.content
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_content(&mut self, content: String) {
|
||||||
|
self.content = content;
|
||||||
|
self.modified = Utc::now();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modified(&self) -> DateTime<Utc> {
|
||||||
|
self.modified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {}
|
mod test {}
|
||||||
|
@ -3,7 +3,7 @@ use std::{io::{BufReader, Read, Write}, path::Path, process::Command};
|
|||||||
use icu_locid::{langid, LanguageIdentifier};
|
use icu_locid::{langid, LanguageIdentifier};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{read_fh, Message, Variant};
|
use crate::{read_fh, Message};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mod bundle;
|
mod bundle;
|
||||||
pub use bundle::Bundle;
|
pub use bundle::{Bundle, Message, Variant};
|
||||||
|
|
||||||
mod editor;
|
mod editor;
|
||||||
pub use editor::Editor;
|
pub use editor::Editor;
|
||||||
@ -7,9 +7,5 @@ pub use editor::Editor;
|
|||||||
mod formats;
|
mod formats;
|
||||||
pub use formats::{js, xliff};
|
pub use formats::{js, xliff};
|
||||||
|
|
||||||
mod types;
|
|
||||||
pub use types::{Message, Variant};
|
|
||||||
|
|
||||||
mod utils;
|
mod utils;
|
||||||
pub use utils::*;
|
pub use utils::*;
|
||||||
|
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
use std::{
|
|
||||||
collections::HashMap,
|
|
||||||
io::{BufReader, Read},
|
|
||||||
path::Path,
|
|
||||||
};
|
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use icu_locid::LanguageIdentifier;
|
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
|
||||||
pub struct Message {
|
|
||||||
key: String,
|
|
||||||
description: String,
|
|
||||||
variants: HashMap<LanguageIdentifier, Variant>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Message {
|
|
||||||
pub fn new(key: String) -> Self {
|
|
||||||
Self {
|
|
||||||
key,
|
|
||||||
description: "".to_owned(),
|
|
||||||
variants: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_file(path: &Path) -> Message {
|
|
||||||
let file = std::fs::File::open(path).unwrap();
|
|
||||||
let mut content = Vec::new();
|
|
||||||
let mut reader = BufReader::new(file);
|
|
||||||
let _ = reader.read_to_end(&mut content);
|
|
||||||
toml::from_str(&String::from_utf8(content).unwrap()).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_description(&mut self, desc: String) {
|
|
||||||
self.description = desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn description(&self) -> &str {
|
|
||||||
&self.description
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn variant(&self, locale: &LanguageIdentifier) -> Option<&Variant> {
|
|
||||||
self.variants.get(locale)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn variant_mut(&mut self, locale: LanguageIdentifier) -> &mut Variant {
|
|
||||||
self.variants.entry(locale.clone()).or_insert(Variant {
|
|
||||||
locale,
|
|
||||||
content: "".to_owned(),
|
|
||||||
modified: Utc::now(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn variants_out_of_date(
|
|
||||||
&self,
|
|
||||||
base_locale: &LanguageIdentifier,
|
|
||||||
) -> Vec<LanguageIdentifier> {
|
|
||||||
match self
|
|
||||||
.variants
|
|
||||||
.get(base_locale)
|
|
||||||
.map(|variant| variant.modified())
|
|
||||||
{
|
|
||||||
Some(base_date) => self
|
|
||||||
.variants
|
|
||||||
.iter()
|
|
||||||
.filter(|(_, value)| base_date > value.modified())
|
|
||||||
.map(|(locale, _)| locale.clone())
|
|
||||||
.collect(),
|
|
||||||
None => vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn missing_variants(&self, locals: Vec<LanguageIdentifier>) -> Vec<LanguageIdentifier> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
|
||||||
pub struct Variant {
|
|
||||||
locale: LanguageIdentifier,
|
|
||||||
content: String,
|
|
||||||
modified: DateTime<Utc>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Variant {
|
|
||||||
pub fn content(&self) -> &str {
|
|
||||||
&self.content
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_content(&mut self, content: String) {
|
|
||||||
self.content = content;
|
|
||||||
self.modified = Utc::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn modified(&self) -> DateTime<Utc> {
|
|
||||||
self.modified
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
fn time_to_number<S>(time: &DateTime, s: S) -> Result<S::Ok, S::Error>
|
|
||||||
where S: Serializer {
|
|
||||||
let seconds: u64 = time.as_secs();
|
|
||||||
s.serialize_u64(seconds)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn number_to_time<'de, D>(d: D) -> Result<DateTime, D::Error>
|
|
||||||
where D: Deserializer<'de> {
|
|
||||||
let buf = String::deserialize(d)?;
|
|
||||||
let num = buf.parse::<u64>().unwrap();
|
|
||||||
Ok(DateTime::try_from(num).unwrap())
|
|
||||||
}
|
|
||||||
*/
|
|
Loading…
Reference in New Issue
Block a user