Skip to content

Commit e61a668

Browse files
committed
feat: better translations (locale O(1) lookup)
1 parent 1f2d54b commit e61a668

File tree

11 files changed

+184
-288
lines changed

11 files changed

+184
-288
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

macros/Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

macros/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition = "2021"
77
proc-macro = true
88

99
[dependencies]
10+
convert_case = "0.7.1"
1011
proc-macro2 = "1.0.93"
1112
quote = "1.0.38"
1213
serde = { version = "1.0.217", features = ["derive"] }

macros/src/translations.rs

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
use convert_case::Casing;
12
use proc_macro::TokenStream;
23
use quote::{format_ident, quote};
34
use serde::Deserialize;
45
use syn::{
56
parse::{Parse, ParseStream},
6-
Ident, LitStr, Token,
7+
LitStr,
78
};
89

910
#[derive(Debug, Deserialize, Clone)]
@@ -16,47 +17,40 @@ pub struct TranslationRecord {
1617
#[allow(dead_code)]
1718
struct TranslationsHandler {
1819
path: String,
19-
name: Ident,
2020
}
2121

2222
impl Parse for TranslationsHandler {
2323
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
2424
let path = input.parse::<LitStr>()?;
25-
input.parse::<Token![,]>()?;
26-
let name = input.parse::<Ident>()?;
2725

28-
Ok(TranslationsHandler {
29-
path: path.value(),
30-
name,
31-
})
26+
Ok(TranslationsHandler { path: path.value() })
3227
}
3328
}
3429

3530
pub fn load_translations_macro(args: TokenStream) -> TokenStream {
36-
let TranslationsHandler { path, name } = syn::parse_macro_input!(args as TranslationsHandler);
31+
let TranslationsHandler { path } = syn::parse_macro_input!(args as TranslationsHandler);
3732

3833
let read = std::fs::read(&path).unwrap();
3934
let translations: Vec<TranslationRecord> = serde_json::from_slice(&read).unwrap();
4035

4136
let translations_count = translations.len();
4237
let declaration = quote! {
43-
pub const #name: [&'static str; #translations_count]
38+
pub const TRANSLATIONS_COUNT: usize = #translations_count;
39+
pub const FALLBACK_TRANSLATIONS: [&'static str; TRANSLATIONS_COUNT]
4440
};
4541

46-
let mut enum_keys = Vec::new();
42+
let mut translation_keys = Vec::new();
4743
let mut enum_parser_keys = Vec::new();
4844
let mut translations_strings = Vec::new();
4945

5046
for (i, TranslationRecord { key, translation }) in translations.iter().enumerate() {
51-
let i = i as isize;
52-
53-
let enum_key = format_ident!("{}", uppercase_first_letter(&key));
54-
enum_keys.push(quote! {
55-
#enum_key = #i,
47+
let translation_key = format_ident!("{}", key.to_case(convert_case::Case::Constant));
48+
translation_keys.push(quote! {
49+
pub const #translation_key: usize = #i;
5650
});
5751

5852
enum_parser_keys.push(quote! {
59-
#key => Some(Self::#enum_key),
53+
#key => Some(Self::#translation_key),
6054
});
6155

6256
translations_strings.push(quote! {
@@ -65,17 +59,12 @@ pub fn load_translations_macro(args: TokenStream) -> TokenStream {
6559
}
6660

6761
quote! {
68-
#[derive(Clone, Copy)]
69-
pub enum TranslationKey {
70-
#(#enum_keys)*
71-
}
62+
pub struct TranslationKey {}
7263

7364
impl TranslationKey {
74-
pub fn to_usize(&self) -> usize {
75-
*self as usize
76-
}
65+
#(#translation_keys)*
7766

78-
pub fn from_key_str(input: &str) -> Option<Self> {
67+
pub fn from_key_str(input: &str) -> Option<usize> {
7968
match input {
8069
#(#enum_parser_keys)*
8170
_ => None
@@ -89,20 +78,3 @@ pub fn load_translations_macro(args: TokenStream) -> TokenStream {
8978
}
9079
.into()
9180
}
92-
93-
// not performent, i know, i dont care
94-
fn uppercase_first_letter(input: &str) -> String {
95-
let mut tmp = String::new();
96-
97-
let mut first = true;
98-
for c in input.chars() {
99-
if first {
100-
tmp.push(c.to_uppercase().nth(0).unwrap());
101-
first = false;
102-
} else {
103-
tmp.push(c);
104-
}
105-
}
106-
107-
tmp
108-
}

0 commit comments

Comments
 (0)