diff options
Diffstat (limited to 'server/locale')
-rw-r--r-- | server/locale/src/lib.rs | 15 | ||||
-rw-r--r-- | server/locale/src/message.rs | 76 |
2 files changed, 86 insertions, 5 deletions
diff --git a/server/locale/src/lib.rs b/server/locale/src/lib.rs index 1d01e4e1..9d55c7cd 100644 --- a/server/locale/src/lib.rs +++ b/server/locale/src/lib.rs @@ -16,6 +16,8 @@ */ +pub mod message; + use anyhow::anyhow; use hurrycurry_protocol::Message; use std::{ @@ -122,15 +124,15 @@ macro_rules! tre_param { }; } -pub struct Strings(HashMap<String, String>); -impl Index<&'static str> for Strings { +pub struct Locale(HashMap<String, String>); +impl Index<&'static str> for Locale { type Output = str; fn index(&self, index: &'static str) -> &Self::Output { self.0.get(index).map(|s| s.as_str()).unwrap_or(index) } } -impl Strings { +impl Locale { pub fn load() -> anyhow::Result<Self> { Ok(Self( include_str!("../../../locale/en.ini") @@ -146,9 +148,12 @@ impl Strings { .collect::<anyhow::Result<HashMap<_, _>>>()?, )) } + pub fn get(&self, id: &str) -> Option<&str> { + self.0.get(id).map(|x| x.as_str()) + } } -static TR: LazyLock<Strings> = LazyLock::new(|| Strings::load().unwrap()); +pub static FALLBACK_LOCALE: LazyLock<Locale> = LazyLock::new(|| Locale::load().unwrap()); pub fn tr(s: &'static str) -> &'static str { - &TR[s] + &FALLBACK_LOCALE[s] } diff --git a/server/locale/src/message.rs b/server/locale/src/message.rs new file mode 100644 index 00000000..bedf45fd --- /dev/null +++ b/server/locale/src/message.rs @@ -0,0 +1,76 @@ +/* + Hurry Curry! - a game about cooking + Copyright (C) 2025 Hurry Curry! Contributors + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ + +use crate::Locale; +use hurrycurry_protocol::{Gamedata, Message}; + +pub trait MessageDisplayExt { + fn display_message(&self, locale: &Locale, data: &Gamedata, style: &DisplayStyle) -> String; +} +impl MessageDisplayExt for Message { + fn display_message(&self, locale: &Locale, data: &Gamedata, style: &DisplayStyle) -> String { + display_message_inner(self, locale, data, style) + } +} +fn display_message_inner( + message: &Message, + locale: &Locale, + data: &Gamedata, + style: &DisplayStyle, +) -> String { + let DisplayStyle { + default, + error, + tile_item, + highlighted, + } = style; + match message { + Message::Translation { id, params } => { + let Some(template) = locale.get(&id) else { + return format!("[translation missing: {error}{id}{default}]"); + }; + let mut s = template.to_string(); + for (i, p) in params.iter().enumerate() { + s = s.replace(&format!("{{{i}}}"), &p.display_message(locale, data, style)); + } + s + } + Message::Text(s) => format!("{highlighted}{s}{default}"), + Message::Item(item_index) => format!("{tile_item}{}{default}", data.item_name(*item_index)), + Message::Tile(tile_index) => format!("{tile_item}{}{default}", data.tile_name(*tile_index)), + } +} + +pub struct DisplayStyle<'a> { + default: &'a str, + error: &'a str, + tile_item: &'a str, + highlighted: &'a str, +} +pub static PLAIN: DisplayStyle = DisplayStyle { + default: "", + error: "", + tile_item: "", + highlighted: "", +}; +pub static COLORED: DisplayStyle = DisplayStyle { + default: "\x1b[0m", + error: "\x1b[31m", + tile_item: "\x1b[34m", + highlighted: "\x1b[1m", +}; |