Add a configuration file
This commit is contained in:
parent
1c3d0711e1
commit
200c13a14e
@ -9,6 +9,7 @@ clap = { version = "4.5.30", features = ["derive"] }
|
|||||||
icu_locid = { version = "1.5.0", features = ["serde"] }
|
icu_locid = { version = "1.5.0", features = ["serde"] }
|
||||||
serde = { version = "1.0.218", features = ["derive"] }
|
serde = { version = "1.0.218", features = ["derive"] }
|
||||||
tempfile = "3.17.1"
|
tempfile = "3.17.1"
|
||||||
|
thiserror = "2.0.11"
|
||||||
toml = "0.8.20"
|
toml = "0.8.20"
|
||||||
|
|
||||||
# [lib]
|
# [lib]
|
||||||
|
8
l10n-db/config.toml
Normal file
8
l10n-db/config.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
db_path = "./i18n"
|
||||||
|
base_locale = "en"
|
||||||
|
locales = [
|
||||||
|
"en",
|
||||||
|
"eo",
|
||||||
|
"de",
|
||||||
|
"es",
|
||||||
|
]
|
@ -1,7 +1,12 @@
|
|||||||
key = "OpenSandbox"
|
key = "OpenSandbox"
|
||||||
description = "A sandbox vault refers to a stock vault that contains test data and allows the user to make edits and run experiments on test data."
|
description = "A sandbox vault refers to a stock vault that contains test data and allows the user to make edits and run experiments on test data."
|
||||||
|
|
||||||
[variants.en-US]
|
[variants.eo]
|
||||||
locale = "en-US"
|
locale = "eo"
|
||||||
|
content = "Malfermi sekurkofro"
|
||||||
|
modified = "2025-02-22T23:35:29.692299091Z"
|
||||||
|
|
||||||
|
[variants.en]
|
||||||
|
locale = "en"
|
||||||
content = "Open Sandbox vault"
|
content = "Open Sandbox vault"
|
||||||
modified = "2025-02-22T21:35:02.032300406Z"
|
modified = "2025-02-22T21:35:02.032300406Z"
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
use std::{io::{BufReader, Read, Write}, path::PathBuf, process::Command};
|
use std::{
|
||||||
|
io::{BufReader, Read, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
use icu_locid::{langid, LanguageIdentifier};
|
use icu_locid::{langid, LanguageIdentifier};
|
||||||
use l10n_db::{self, Bundle, Editor};
|
use l10n_db::{self, read_file, Bundle, Editor, ReadError};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
@ -15,7 +20,12 @@ struct Cli {
|
|||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Edit, potentially creating, a key
|
/// Edit, potentially creating, a key
|
||||||
EditKey { name: String, locale: String },
|
EditKey {
|
||||||
|
#[arg(short, long)]
|
||||||
|
name: String,
|
||||||
|
#[arg(short, long)]
|
||||||
|
locale: String,
|
||||||
|
},
|
||||||
/// List al keys in the database
|
/// List al keys in the database
|
||||||
ListKeys,
|
ListKeys,
|
||||||
// Search the database
|
// Search the database
|
||||||
@ -25,10 +35,17 @@ enum Commands {
|
|||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
format: String,
|
format: String,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
locale: String
|
locale: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Config {
|
||||||
|
db_path: PathBuf,
|
||||||
|
base_locale: LanguageIdentifier,
|
||||||
|
locales: Vec<LanguageIdentifier>,
|
||||||
|
}
|
||||||
|
|
||||||
fn edit_key(bundle: &mut Bundle, key: String, locale: LanguageIdentifier, editor: &str) {
|
fn edit_key(bundle: &mut Bundle, key: String, locale: LanguageIdentifier, editor: &str) {
|
||||||
let message = bundle.message(key);
|
let message = bundle.message(key);
|
||||||
Editor::edit(message, locale, editor);
|
Editor::edit(message, locale, editor);
|
||||||
@ -36,21 +53,28 @@ fn edit_key(bundle: &mut Bundle, key: String, locale: LanguageIdentifier, editor
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let editor = std::env::var("EDITOR").unwrap();
|
let editor = std::env::var("EDITOR").expect("Set EDITOR to the path to your favorite editor");
|
||||||
let db_path = std::env::var("DB_PATH").unwrap();
|
|
||||||
|
let config: Config = read_file(&PathBuf::from("./config.toml"))
|
||||||
|
.and_then(|bytes| String::from_utf8(bytes).map_err(|_| ReadError::InvalidFormat))
|
||||||
|
.and_then(|content| toml::from_str(&content).map_err(|_| ReadError::InvalidFormat))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let mut bundle = Bundle::load_from_disk(PathBuf::from(&db_path));
|
let mut bundle = Bundle::load_from_disk(PathBuf::from(&config.db_path));
|
||||||
|
|
||||||
match &cli.command {
|
match &cli.command {
|
||||||
Some(Commands::EditKey{ name, locale } ) => edit_key(&mut bundle, name.to_owned(), langid!("en-US"), &editor),
|
Some(Commands::EditKey { name, locale }) => {
|
||||||
|
let identifier = locale.parse::<LanguageIdentifier>().unwrap();
|
||||||
|
edit_key(&mut bundle, name.to_owned(), identifier, &editor)
|
||||||
|
}
|
||||||
Some(Commands::ListKeys) => {
|
Some(Commands::ListKeys) => {
|
||||||
for (key, _) in bundle.message_iter() {
|
for (key, _) in bundle.message_iter() {
|
||||||
println!("{}", key);
|
println!("{}", key);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Some(Commands::Export{..}) => todo!(),
|
Some(Commands::Export { .. }) => todo!(),
|
||||||
None => {},
|
None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
use std::{io::{BufReader, Read, Write}, path::Path, process::Command};
|
use std::{io::{BufReader, Read, Write}, path::Path, process::Command};
|
||||||
|
|
||||||
use icu_locid::LanguageIdentifier;
|
use icu_locid::{langid, LanguageIdentifier};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{Message, Variant};
|
use crate::{read_fh, Message, Variant};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
struct EditorMessage {
|
struct EditorMessage {
|
||||||
description: String,
|
description: String,
|
||||||
|
source: String,
|
||||||
content: String,
|
content: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
impl EditorMessage {
|
impl EditorMessage {
|
||||||
fn from_variant(description: String, variant: &Variant) -> Self {
|
fn from_variant(description: String, variant: &Variant) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -20,6 +22,7 @@ impl EditorMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
}
|
}
|
||||||
@ -27,8 +30,14 @@ pub struct Editor {
|
|||||||
impl Editor {
|
impl Editor {
|
||||||
pub fn edit(msg: &mut Message, locale: LanguageIdentifier, editor: &str) {
|
pub fn edit(msg: &mut Message, locale: LanguageIdentifier, editor: &str) {
|
||||||
let description = msg.description().to_owned();
|
let description = msg.description().to_owned();
|
||||||
|
let source_string = msg.variant_mut(langid!("en")).content().to_owned();
|
||||||
let variant = msg.variant_mut(locale);
|
let variant = msg.variant_mut(locale);
|
||||||
let editable_content = EditorMessage::from_variant(description, &variant);
|
// let editable_content = EditorMessage::from_variant(description, &variant);
|
||||||
|
let editable_content = EditorMessage {
|
||||||
|
description,
|
||||||
|
source: source_string,
|
||||||
|
content: variant.content().to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut file = tempfile::NamedTempFile::new().unwrap();
|
let mut file = tempfile::NamedTempFile::new().unwrap();
|
||||||
let _ = file.write(toml::to_string(&editable_content).unwrap().as_bytes());
|
let _ = file.write(toml::to_string(&editable_content).unwrap().as_bytes());
|
||||||
@ -36,12 +45,7 @@ impl Editor {
|
|||||||
let mut cmd = Command::new(editor).args([file.path()]).spawn().unwrap();
|
let mut cmd = Command::new(editor).args([file.path()]).spawn().unwrap();
|
||||||
cmd.wait().unwrap();
|
cmd.wait().unwrap();
|
||||||
let file = file.reopen().unwrap();
|
let file = file.reopen().unwrap();
|
||||||
let mut reader = BufReader::new(file);
|
let content = read_fh(&file).unwrap();
|
||||||
let mut content = Vec::new();
|
|
||||||
let _ = reader.read_to_end(&mut content);
|
|
||||||
|
|
||||||
println!("content");
|
|
||||||
println!("{}", String::from_utf8(content.clone()).unwrap());
|
|
||||||
|
|
||||||
let new_variant: EditorMessage = toml::from_str(&String::from_utf8(content).unwrap()).unwrap();
|
let new_variant: EditorMessage = toml::from_str(&String::from_utf8(content).unwrap()).unwrap();
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@ pub use editor::Editor;
|
|||||||
mod types;
|
mod types;
|
||||||
pub use types::{Message, Variant};
|
pub use types::{Message, Variant};
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
pub use utils::*;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
@ -45,7 +45,7 @@ impl Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
pub struct Variant {
|
pub struct Variant {
|
||||||
locale: LanguageIdentifier,
|
locale: LanguageIdentifier,
|
||||||
content: String,
|
content: String,
|
||||||
|
31
l10n-db/src/utils.rs
Normal file
31
l10n-db/src/utils.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use std::{fs::File, io::{BufReader, ErrorKind, Read}, path::Path};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
pub enum ReadError {
|
||||||
|
#[error("file not found")]
|
||||||
|
FileNotFound,
|
||||||
|
|
||||||
|
#[error("invalid file format")]
|
||||||
|
InvalidFormat,
|
||||||
|
|
||||||
|
#[error("unhandled read error")]
|
||||||
|
Unhandled(ErrorKind),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_file(path: &Path) -> Result<Vec<u8>, ReadError> {
|
||||||
|
let file = File::open(path).map_err(|err| {
|
||||||
|
match err.kind() {
|
||||||
|
ErrorKind::NotFound => ReadError::FileNotFound,
|
||||||
|
_ => ReadError::Unhandled( err.kind()),
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
read_fh(&file)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_fh(file: &File) -> Result<Vec<u8>, ReadError> {
|
||||||
|
let mut content = Vec::new();
|
||||||
|
let mut reader = BufReader::new(file);
|
||||||
|
reader.read_to_end(&mut content).map_err(|err| ReadError::Unhandled(err.kind()))?;
|
||||||
|
Ok(content)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user