Compare commits
No commits in common. "8ceca454b16357da36fe3534bb289b9b49d38f15" and "137a88ad8e40976d93768cc2defde5acec0d6965" have entirely different histories.
8ceca454b1
...
137a88ad8e
|
@ -2710,6 +2710,13 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kifu-l10n"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"messages-codegen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kv-log-macro"
|
name = "kv-log-macro"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -2725,15 +2732,12 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
"convert_case",
|
|
||||||
"fixed_decimal",
|
"fixed_decimal",
|
||||||
"fluent",
|
"fluent",
|
||||||
"fluent-ergonomics",
|
"fluent-ergonomics",
|
||||||
"icu",
|
"icu",
|
||||||
"icu_locid",
|
"icu_locid",
|
||||||
"icu_provider",
|
"icu_provider",
|
||||||
"serde 1.0.193",
|
|
||||||
"serde_yaml",
|
|
||||||
"sys-locale",
|
"sys-locale",
|
||||||
"unic-langid",
|
"unic-langid",
|
||||||
]
|
]
|
||||||
|
@ -2913,6 +2917,17 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "messages-codegen"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"convert_case",
|
||||||
|
"quote",
|
||||||
|
"serde 1.0.193",
|
||||||
|
"serde_yaml",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|
95
Cargo.nix
95
Cargo.nix
|
@ -2249,25 +2249,6 @@ rec {
|
||||||
"arbitrary" = [ "dep:arbitrary" ];
|
"arbitrary" = [ "dep:arbitrary" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
"convert_case" = rec {
|
|
||||||
crateName = "convert_case";
|
|
||||||
version = "0.6.0";
|
|
||||||
edition = "2018";
|
|
||||||
sha256 = "1jn1pq6fp3rri88zyw6jlhwwgf6qiyc08d6gjv0qypgkl862n67c";
|
|
||||||
authors = [
|
|
||||||
"Rutrum <dave@rutrum.net>"
|
|
||||||
];
|
|
||||||
dependencies = [
|
|
||||||
{
|
|
||||||
name = "unicode-segmentation";
|
|
||||||
packageId = "unicode-segmentation";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
features = {
|
|
||||||
"rand" = [ "dep:rand" ];
|
|
||||||
"random" = [ "rand" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"cookie" = rec {
|
"cookie" = rec {
|
||||||
crateName = "cookie";
|
crateName = "cookie";
|
||||||
version = "0.17.0";
|
version = "0.17.0";
|
||||||
|
@ -8812,18 +8793,6 @@ rec {
|
||||||
crateName = "l10n";
|
crateName = "l10n";
|
||||||
version = "0.1.0";
|
version = "0.1.0";
|
||||||
edition = "2021";
|
edition = "2021";
|
||||||
crateBin = [
|
|
||||||
{
|
|
||||||
name = "codegen-rust";
|
|
||||||
path = "src/bin/codegen-rust.rs";
|
|
||||||
requiredFeatures = [ ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "msggen";
|
|
||||||
path = "src/bin/msggen.rs";
|
|
||||||
requiredFeatures = [ ];
|
|
||||||
}
|
|
||||||
];
|
|
||||||
# We can't filter paths with references in Nix 2.4
|
# We can't filter paths with references in Nix 2.4
|
||||||
# See https://github.com/NixOS/nix/issues/5410
|
# See https://github.com/NixOS/nix/issues/5410
|
||||||
src = if ((lib.versionOlder builtins.nixVersion "2.4pre20211007") || (lib.versionOlder "2.5" builtins.nixVersion ))
|
src = if ((lib.versionOlder builtins.nixVersion "2.4pre20211007") || (lib.versionOlder "2.5" builtins.nixVersion ))
|
||||||
|
@ -8838,10 +8807,6 @@ rec {
|
||||||
name = "chrono-tz";
|
name = "chrono-tz";
|
||||||
packageId = "chrono-tz";
|
packageId = "chrono-tz";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "convert_case";
|
|
||||||
packageId = "convert_case";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "fixed_decimal";
|
name = "fixed_decimal";
|
||||||
packageId = "fixed_decimal";
|
packageId = "fixed_decimal";
|
||||||
|
@ -8851,10 +8816,6 @@ rec {
|
||||||
name = "fluent";
|
name = "fluent";
|
||||||
packageId = "fluent";
|
packageId = "fluent";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "fluent-ergonomics";
|
|
||||||
packageId = "fluent-ergonomics";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "icu";
|
name = "icu";
|
||||||
packageId = "icu";
|
packageId = "icu";
|
||||||
|
@ -8867,23 +8828,10 @@ rec {
|
||||||
name = "icu_provider";
|
name = "icu_provider";
|
||||||
packageId = "icu_provider";
|
packageId = "icu_provider";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "serde";
|
|
||||||
packageId = "serde 1.0.193";
|
|
||||||
features = [ "derive" ];
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "serde_yaml";
|
|
||||||
packageId = "serde_yaml";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "sys-locale";
|
name = "sys-locale";
|
||||||
packageId = "sys-locale";
|
packageId = "sys-locale";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "unic-langid";
|
|
||||||
packageId = "unic-langid";
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -13229,38 +13177,6 @@ rec {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
|
||||||
"serde_yaml" = rec {
|
|
||||||
crateName = "serde_yaml";
|
|
||||||
version = "0.9.29";
|
|
||||||
edition = "2021";
|
|
||||||
sha256 = "0aci065jjqjwxn4qm27r4li20w1wfdd6vgx0j34affgrdgv0wpm1";
|
|
||||||
authors = [
|
|
||||||
"David Tolnay <dtolnay@gmail.com>"
|
|
||||||
];
|
|
||||||
dependencies = [
|
|
||||||
{
|
|
||||||
name = "indexmap";
|
|
||||||
packageId = "indexmap";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "itoa";
|
|
||||||
packageId = "itoa";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "ryu";
|
|
||||||
packageId = "ryu";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "serde";
|
|
||||||
packageId = "serde 1.0.193";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = "unsafe-libyaml";
|
|
||||||
packageId = "unsafe-libyaml";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
"sgf" = rec {
|
"sgf" = rec {
|
||||||
crateName = "sgf";
|
crateName = "sgf";
|
||||||
|
@ -16241,17 +16157,6 @@ rec {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
|
||||||
"unsafe-libyaml" = rec {
|
|
||||||
crateName = "unsafe-libyaml";
|
|
||||||
version = "0.2.10";
|
|
||||||
edition = "2021";
|
|
||||||
crateBin = [];
|
|
||||||
sha256 = "0jsyc1kqc536wpgx1js61lwj86crniqw16lyvh02va4m1f9r0k5b";
|
|
||||||
authors = [
|
|
||||||
"David Tolnay <dtolnay@gmail.com>"
|
|
||||||
];
|
|
||||||
|
|
||||||
};
|
};
|
||||||
"url 1.7.2" = rec {
|
"url 1.7.2" = rec {
|
||||||
crateName = "url";
|
crateName = "url";
|
||||||
|
|
|
@ -20,8 +20,10 @@ members = [
|
||||||
"ifc",
|
"ifc",
|
||||||
"kifu/core",
|
"kifu/core",
|
||||||
"kifu/gtk",
|
"kifu/gtk",
|
||||||
|
"kifu/l10n",
|
||||||
"l10n",
|
"l10n",
|
||||||
"memorycache",
|
"memorycache",
|
||||||
|
"messages-codegen",
|
||||||
"nom-training",
|
"nom-training",
|
||||||
"result-extended",
|
"result-extended",
|
||||||
"screenplay",
|
"screenplay",
|
||||||
|
|
15
flake.nix
15
flake.nix
|
@ -86,17 +86,6 @@
|
||||||
file-service = cargo_nix.workspaceMembers.file-service.build;
|
file-service = cargo_nix.workspaceMembers.file-service.build;
|
||||||
fitnesstrax = cargo_nix.workspaceMembers.fitnesstrax.build;
|
fitnesstrax = cargo_nix.workspaceMembers.fitnesstrax.build;
|
||||||
kifu-gtk = cargo_nix.workspaceMembers.kifu-gtk.build;
|
kifu-gtk = cargo_nix.workspaceMembers.kifu-gtk.build;
|
||||||
l10n = cargo_nix.workspaceMembers.l10n.build;
|
|
||||||
l10n-codegen-rust = pkgs.stdenv.mkDerivation {
|
|
||||||
name = "l10n-codegen-rust";
|
|
||||||
src = ./.;
|
|
||||||
buildInputs = [ l10n ];
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
cp ${l10n}/bin/codegen-rust $out/bin/l10n-codegen-rust
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
xdg-test = cargo_nix.workspaceMembers.xdg-test.build;
|
xdg-test = cargo_nix.workspaceMembers.xdg-test.build;
|
||||||
|
|
||||||
all = pkgs.symlinkJoin {
|
all = pkgs.symlinkJoin {
|
||||||
|
@ -106,9 +95,7 @@
|
||||||
dashboard
|
dashboard
|
||||||
file-service
|
file-service
|
||||||
fitnesstrax
|
fitnesstrax
|
||||||
# kifu-gtk
|
kifu-gtk
|
||||||
l10n
|
|
||||||
l10n-codegen-rust
|
|
||||||
xdg-test
|
xdg-test
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,11 +4,4 @@ fn main() {
|
||||||
"gresources.xml",
|
"gresources.xml",
|
||||||
"com.luminescent-dreams.kifu-gtk.gresource",
|
"com.luminescent-dreams.kifu-gtk.gresource",
|
||||||
);
|
);
|
||||||
|
|
||||||
let messages = std::process::Command::new("codegen-rust")
|
|
||||||
.arg("messages/en.yaml")
|
|
||||||
.output()
|
|
||||||
.expect("Failed to execute command");
|
|
||||||
|
|
||||||
println!("{}", String::from_utf8(messages.stdout).unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,20 +6,14 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chrono-tz = { version = "0.8" }
|
|
||||||
chrono = { version = "0.4" }
|
chrono = { version = "0.4" }
|
||||||
convert_case = { version = "0.6" }
|
chrono-tz = { version = "0.8" }
|
||||||
fixed_decimal = { version = "0.5.5", features = [ "ryu" ] }
|
fixed_decimal = { version = "0.5.5", features = [ "ryu" ] }
|
||||||
fluent-ergonomics = { path = "../fluent-ergonomics" }
|
|
||||||
fluent = { version = "0.16" }
|
fluent = { version = "0.16" }
|
||||||
|
fluent-ergonomics = { path = "../fluent-ergonomics" }
|
||||||
|
icu = { version = "1" }
|
||||||
icu_locid = { version = "1" }
|
icu_locid = { version = "1" }
|
||||||
icu_provider = { version = "1" }
|
icu_provider = { version = "1" }
|
||||||
icu = { version = "1" }
|
|
||||||
serde = { version = "1", features = [ "derive" ] }
|
|
||||||
serde_yaml = { version = "0.9" }
|
|
||||||
sys-locale = { version = "0.3" }
|
sys-locale = { version = "0.3" }
|
||||||
unic-langid = { version = "*" }
|
unic-langid = { version = "*" }
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "codegen-rust"
|
|
||||||
src = "src/bin/codegen-rust.rs"
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
fn main() {
|
|
||||||
println!("msggen running");
|
|
||||||
}
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "messages-codegen"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
convert_case = { version = "0.6" }
|
||||||
|
quote = { version = "*" }
|
||||||
|
syn = { version = "*" }
|
||||||
|
serde_yaml = { version = "*" }
|
||||||
|
serde = { version = "*", features = [ "derive" ] }
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* Given that fluent doesn't provide an ability to see all of the placeholders within a message,
|
||||||
|
* and that the placeholders may change depending on the values of others, I don't have a way to
|
||||||
|
* ensure that the translation code remains entirely connected to the source messages themselves.
|
||||||
|
*
|
||||||
|
* Given that I can't really enforce it, I can, perhaps, codegen it in a way that at least the two
|
||||||
|
* are right next to one another. A macro that generates the data structure and can write the
|
||||||
|
* source strings file.
|
||||||
|
*
|
||||||
|
* For overall file structure, I want the messages, L10N, and FluentErgo tied together.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn;
|
||||||
|
|
||||||
|
/* I want to write a macro that reads something like this:
|
||||||
|
* messages! {
|
||||||
|
* Welcome(name: String) => "Hello, ${name}",
|
||||||
|
* GamesInDatabase(count: usize) => "{$count ->
|
||||||
|
* [one] There is one game in the database
|
||||||
|
* *[other] There are ${count} games in the database
|
||||||
|
* }",
|
||||||
|
*
|
||||||
|
* It generates an enumeration with all of the named values (Welcome, GamesInDatabase), it
|
||||||
|
* generates corresponding structures (Welcome{ name: String }, GamesInDatabase{ count: usize }),
|
||||||
|
* and it generates two implementations. One is an implementation that can be used to write all of
|
||||||
|
* the strings after => into a file. The other is an implementation that can be imported into a
|
||||||
|
* program, but which *does not* contain the strings. That would look more like this:
|
||||||
|
*
|
||||||
|
* messages.rs:
|
||||||
|
*
|
||||||
|
* enum Messages {
|
||||||
|
* Welcome(Welcome),
|
||||||
|
* GamesInDatabase(GamesInDatabase),
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* struct Welcome{ name: String }
|
||||||
|
* struct GamesInDatabase{ count: usize }
|
||||||
|
*
|
||||||
|
* message_strings.ftl:
|
||||||
|
*
|
||||||
|
* welcome = "Hello, ${name}",
|
||||||
|
* games-in-database = "{$count ->
|
||||||
|
* [one] There is one game in the database
|
||||||
|
* *[other] There are ${count} games in the database
|
||||||
|
* }",
|
||||||
|
*
|
||||||
|
* messages.rs can be imported into the resulting program, and the names of the strings are thus a
|
||||||
|
* part of the program, but the strings themselves are still data files.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! messages {
|
||||||
|
($($name:ident($($arg:ident: $argtype:ty)*) => $message:literal,)+) => {
|
||||||
|
pub enum Messages {
|
||||||
|
$($name($name)),+
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Messages {
|
||||||
|
fn gen_strings() -> Vec<String> {
|
||||||
|
vec![
|
||||||
|
$(concat!(stringify!($name), " => ", $message).to_string(),)+
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(pub struct $name {
|
||||||
|
$($arg: $argtype)*
|
||||||
|
})+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#[proc_macro_derive(Messages)]
|
||||||
|
pub fn messages_macro(input: TokenStream) -> TokenStream {
|
||||||
|
let syn::DeriveInput { ident, .. } = syn::parse_macro_input! {input};
|
||||||
|
|
||||||
|
let gen = quote! {
|
||||||
|
impl Messages for #ident {
|
||||||
|
fn hello() {
|
||||||
|
println!("Hello from {}", stringify!(#ident));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
gen.into()
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_yaml;
|
use serde_yaml;
|
||||||
use std::{collections::HashMap, fmt, fs::File, env};
|
use std::{collections::HashMap, fmt, fs::File};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
struct MessageJS {
|
struct MessageJS {
|
||||||
|
@ -121,11 +121,8 @@ impl Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut args = env::args();
|
|
||||||
let _ = args.next();
|
|
||||||
let input_file = args.next().unwrap();
|
|
||||||
let messages: HashMap<String, MessageJS> =
|
let messages: HashMap<String, MessageJS> =
|
||||||
serde_yaml::from_reader(File::open(input_file).unwrap()).unwrap();
|
serde_yaml::from_reader(File::open("test-data/messages.yaml").unwrap()).unwrap();
|
||||||
|
|
||||||
let messages = messages
|
let messages = messages
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -133,5 +130,6 @@ fn main() {
|
||||||
for message in messages {
|
for message in messages {
|
||||||
println!();
|
println!();
|
||||||
println!("{}", message.rust_code());
|
println!("{}", message.rust_code());
|
||||||
|
// println!("{}", message.content());
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue