Compare commits
4 Commits
137a88ad8e
...
8ceca454b1
Author | SHA1 | Date |
---|---|---|
Savanni D'Gerinel | 8ceca454b1 | |
Savanni D'Gerinel | 30198f0038 | |
Savanni D'Gerinel | 1881fb99ce | |
Savanni D'Gerinel | 4cfc6425e1 |
|
@ -2710,13 +2710,6 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kifu-l10n"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"messages-codegen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kv-log-macro"
|
||||
version = "1.0.7"
|
||||
|
@ -2732,12 +2725,15 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz",
|
||||
"convert_case",
|
||||
"fixed_decimal",
|
||||
"fluent",
|
||||
"fluent-ergonomics",
|
||||
"icu",
|
||||
"icu_locid",
|
||||
"icu_provider",
|
||||
"serde 1.0.193",
|
||||
"serde_yaml",
|
||||
"sys-locale",
|
||||
"unic-langid",
|
||||
]
|
||||
|
@ -2917,17 +2913,6 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "messages-codegen"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"quote",
|
||||
"serde 1.0.193",
|
||||
"serde_yaml",
|
||||
"syn 2.0.48",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.2.6"
|
||||
|
|
95
Cargo.nix
95
Cargo.nix
|
@ -2249,6 +2249,25 @@ rec {
|
|||
"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 {
|
||||
crateName = "cookie";
|
||||
version = "0.17.0";
|
||||
|
@ -8793,6 +8812,18 @@ rec {
|
|||
crateName = "l10n";
|
||||
version = "0.1.0";
|
||||
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
|
||||
# See https://github.com/NixOS/nix/issues/5410
|
||||
src = if ((lib.versionOlder builtins.nixVersion "2.4pre20211007") || (lib.versionOlder "2.5" builtins.nixVersion ))
|
||||
|
@ -8807,6 +8838,10 @@ rec {
|
|||
name = "chrono-tz";
|
||||
packageId = "chrono-tz";
|
||||
}
|
||||
{
|
||||
name = "convert_case";
|
||||
packageId = "convert_case";
|
||||
}
|
||||
{
|
||||
name = "fixed_decimal";
|
||||
packageId = "fixed_decimal";
|
||||
|
@ -8816,6 +8851,10 @@ rec {
|
|||
name = "fluent";
|
||||
packageId = "fluent";
|
||||
}
|
||||
{
|
||||
name = "fluent-ergonomics";
|
||||
packageId = "fluent-ergonomics";
|
||||
}
|
||||
{
|
||||
name = "icu";
|
||||
packageId = "icu";
|
||||
|
@ -8828,10 +8867,23 @@ rec {
|
|||
name = "icu_provider";
|
||||
packageId = "icu_provider";
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde 1.0.193";
|
||||
features = [ "derive" ];
|
||||
}
|
||||
{
|
||||
name = "serde_yaml";
|
||||
packageId = "serde_yaml";
|
||||
}
|
||||
{
|
||||
name = "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 {
|
||||
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 {
|
||||
crateName = "url";
|
||||
|
|
|
@ -20,10 +20,8 @@ members = [
|
|||
"ifc",
|
||||
"kifu/core",
|
||||
"kifu/gtk",
|
||||
"kifu/l10n",
|
||||
"l10n",
|
||||
"memorycache",
|
||||
"messages-codegen",
|
||||
"nom-training",
|
||||
"result-extended",
|
||||
"screenplay",
|
||||
|
|
15
flake.nix
15
flake.nix
|
@ -86,6 +86,17 @@
|
|||
file-service = cargo_nix.workspaceMembers.file-service.build;
|
||||
fitnesstrax = cargo_nix.workspaceMembers.fitnesstrax.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;
|
||||
|
||||
all = pkgs.symlinkJoin {
|
||||
|
@ -95,7 +106,9 @@
|
|||
dashboard
|
||||
file-service
|
||||
fitnesstrax
|
||||
kifu-gtk
|
||||
# kifu-gtk
|
||||
l10n
|
||||
l10n-codegen-rust
|
||||
xdg-test
|
||||
];
|
||||
};
|
||||
|
|
|
@ -4,4 +4,11 @@ fn main() {
|
|||
"gresources.xml",
|
||||
"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,14 +6,20 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
chrono = { version = "0.4" }
|
||||
chrono-tz = { version = "0.8" }
|
||||
chrono = { version = "0.4" }
|
||||
convert_case = { version = "0.6" }
|
||||
fixed_decimal = { version = "0.5.5", features = [ "ryu" ] }
|
||||
fluent = { version = "0.16" }
|
||||
fluent-ergonomics = { path = "../fluent-ergonomics" }
|
||||
icu = { version = "1" }
|
||||
fluent = { version = "0.16" }
|
||||
icu_locid = { version = "1" }
|
||||
icu_provider = { version = "1" }
|
||||
icu = { version = "1" }
|
||||
serde = { version = "1", features = [ "derive" ] }
|
||||
serde_yaml = { version = "0.9" }
|
||||
sys-locale = { version = "0.3" }
|
||||
unic-langid = { version = "*" }
|
||||
|
||||
[[bin]]
|
||||
name = "codegen-rust"
|
||||
src = "src/bin/codegen-rust.rs"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use convert_case::{Case, Casing};
|
||||
use serde::Deserialize;
|
||||
use serde_yaml;
|
||||
use std::{collections::HashMap, fmt, fs::File};
|
||||
use std::{collections::HashMap, fmt, fs::File, env};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct MessageJS {
|
||||
|
@ -121,8 +121,11 @@ impl Message {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args();
|
||||
let _ = args.next();
|
||||
let input_file = args.next().unwrap();
|
||||
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
|
||||
.into_iter()
|
||||
|
@ -130,6 +133,5 @@ fn main() {
|
|||
for message in messages {
|
||||
println!();
|
||||
println!("{}", message.rust_code());
|
||||
// println!("{}", message.content());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
println!("msggen running");
|
||||
}
|
|
@ -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" ] }
|
|
@ -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()
|
||||
}
|
Loading…
Reference in New Issue