Compare commits

..

4 Commits

11 changed files with 136 additions and 130 deletions

21
Cargo.lock generated
View File

@ -2710,13 +2710,6 @@ 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"
@ -2732,12 +2725,15 @@ 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",
] ]
@ -2917,17 +2913,6 @@ 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"

View File

@ -2249,6 +2249,25 @@ 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";
@ -8793,6 +8812,18 @@ 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 ))
@ -8807,6 +8838,10 @@ 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";
@ -8816,6 +8851,10 @@ rec {
name = "fluent"; name = "fluent";
packageId = "fluent"; packageId = "fluent";
} }
{
name = "fluent-ergonomics";
packageId = "fluent-ergonomics";
}
{ {
name = "icu"; name = "icu";
packageId = "icu"; packageId = "icu";
@ -8828,10 +8867,23 @@ 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";
}
]; ];
}; };
@ -13177,6 +13229,38 @@ 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";
@ -16157,6 +16241,17 @@ 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";

View File

@ -20,10 +20,8 @@ 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",

View File

@ -86,6 +86,17 @@
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 {
@ -95,7 +106,9 @@
dashboard dashboard
file-service file-service
fitnesstrax fitnesstrax
kifu-gtk # kifu-gtk
l10n
l10n-codegen-rust
xdg-test xdg-test
]; ];
}; };

View File

@ -4,4 +4,11 @@ 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());
} }

View File

@ -6,14 +6,20 @@ 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 = { version = "0.4" }
chrono-tz = { version = "0.8" } chrono-tz = { version = "0.8" }
chrono = { version = "0.4" }
convert_case = { version = "0.6" }
fixed_decimal = { version = "0.5.5", features = [ "ryu" ] } fixed_decimal = { version = "0.5.5", features = [ "ryu" ] }
fluent = { version = "0.16" }
fluent-ergonomics = { path = "../fluent-ergonomics" } fluent-ergonomics = { path = "../fluent-ergonomics" }
icu = { version = "1" } fluent = { version = "0.16" }
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"

View File

@ -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}; use std::{collections::HashMap, fmt, fs::File, env};
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
struct MessageJS { struct MessageJS {
@ -121,8 +121,11 @@ 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("test-data/messages.yaml").unwrap()).unwrap(); serde_yaml::from_reader(File::open(input_file).unwrap()).unwrap();
let messages = messages let messages = messages
.into_iter() .into_iter()
@ -130,6 +133,5 @@ fn main() {
for message in messages { for message in messages {
println!(); println!();
println!("{}", message.rust_code()); println!("{}", message.rust_code());
// println!("{}", message.content());
} }
} }

3
l10n/src/bin/msggen.rs Normal file
View File

@ -0,0 +1,3 @@
fn main() {
println!("msggen running");
}

View File

@ -1,16 +0,0 @@
[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" ] }

View File

@ -1,87 +0,0 @@
/* 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()
}