From 1c4e6f9828cf77f722e275f8946d1acb31eba5ac Mon Sep 17 00:00:00 2001 From: Aziz Chynaliev Date: Sun, 9 Oct 2022 02:17:36 +0300 Subject: [PATCH] Feat: text (#1) * Feat: optional text feature * Bump: version to 1.0.4-ss220 * Fix: add C char --- Cargo.lock | 9 ++- Cargo.toml | 4 +- dmsrc/text.dm | 2 + src/lib.rs | 2 + src/text.rs | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 dmsrc/text.dm create mode 100644 src/text.rs diff --git a/Cargo.lock b/Cargo.lock index 994d2c7..5d79093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2186,7 +2186,7 @@ dependencies = [ [[package]] name = "rust-g" -version = "1.0.3-ss220" +version = "1.0.4-ss220" dependencies = [ "aho-corasick", "base64", @@ -2218,6 +2218,7 @@ dependencies = [ "sha2", "thiserror", "toml", + "translit", "twox-hash", "url", "workerpool", @@ -2746,6 +2747,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "translit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e21e0a7cd15b8a1159a6dbcfd96d7bd4f9d050c31143d1ba743c6cfe60a71063" + [[package]] name = "try-lock" version = "0.2.3" diff --git a/Cargo.toml b/Cargo.toml index e668db8..a4d4dab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rust-g" edition = "2021" -version = "1.0.3-ss220" +version = "1.0.4-ss220" authors = ["Bjorn Neergaard ", "Tad Hardesty ", "rust-g maintainer team"] repository = "https://github.com/tgstation/rust-g" license = "MIT" @@ -49,6 +49,7 @@ dbpnoise = { version = "0.1.2", optional = true} pathfinding = { version = "3.0.13", optional = true } num = { version = "0.4.0", optional = true } workerpool = "1.2.0" +translit = { version = "0.5.0", optional = true } [features] default = ["acreplace", "cellularnoise", "dmi", "file", "git", "http", "json", "log", "noise", "sql", "time", "toml", "url"] @@ -74,6 +75,7 @@ pathfinder = [ "num", "pathfinding", "serde", "serde_json"] redis_pubsub = ["flume", "redis", "serde", "serde_json"] unzip = ["zip", "jobs"] worleynoise = ["rand","rayon"] +text = ["translit"] # internal feature-like things jobs = ["flume"] diff --git a/dmsrc/text.dm b/dmsrc/text.dm new file mode 100644 index 0000000..72c751f --- /dev/null +++ b/dmsrc/text.dm @@ -0,0 +1,2 @@ +#define rustg_cyrillic_to_latin(text) call(RUST_G, "cyrillic_to_latin")("[text]") +#define rustg_latin_to_cyrillic(text) call(RUST_G, "latin_to_cyrillic")("[text]") diff --git a/src/lib.rs b/src/lib.rs index bbe4055..ce3645b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,6 +46,8 @@ pub mod unzip; pub mod url; #[cfg(feature = "worleynoise")] pub mod worleynoise; +#[cfg(feature = "text")] +pub mod text; #[cfg(not(target_pointer_width = "32"))] compile_error!("rust-g must be compiled for a 32-bit target"); diff --git a/src/text.rs b/src/text.rs new file mode 100644 index 0000000..0479d77 --- /dev/null +++ b/src/text.rs @@ -0,0 +1,209 @@ +use translit::{Transliterator, CharsMapping}; + +byond_fn!(fn cyrillic_to_latin (string) { + Some(cyr_to_latin(string)) +}); + +byond_fn!(fn latin_to_cyrillic (string) { + Some(latin_to_cyr(string)) +}); + +fn cyr_to_latin(string: &str) -> String { + Transliterator::new(table_to_latin()).convert(string, false) +} + +fn latin_to_cyr(string: &str) -> String { + Transliterator::new(table_from_latin()).convert(string, true) +} + +fn table_to_latin() -> CharsMapping { + [ + ("А", "A"), + ("Б", "B"), + ("В", "V"), + ("Г", "G"), + ("Д", "D"), + ("Е", "E"), + ("Ё", "Yo"), + ("Ж", "Zh"), + ("З", "Z"), + ("И", "I"), + ("Й", "I"), + ("К", "K"), + ("Л", "L"), + ("М", "M"), + ("Н", "N"), + ("О", "O"), + ("П", "P"), + ("Р", "R"), + ("С", "S"), + ("Т", "T"), + ("У", "U"), + ("Ф", "F"), + ("Х", "Kh"), + ("Х", "H"), + ("Ц", "Ts"), + ("Ч", "Ch"), + ("Ш", "Sh"), + ("Щ", "Shch"), + ("Ъ", "Ie"), + ("Ы", "Y"), + ("Ь", "'"), + ("Э", "E"), + ("Ю", "Iu"), + ("Я", "Ia"), + ("а", "a"), + ("б", "b"), + ("в", "v"), + ("г", "g"), + ("д", "d"), + ("е", "e"), + ("ё", "yo"), + ("ж", "zh"), + ("з", "z"), + ("и", "i"), + ("й", "i"), + ("к", "k"), + ("л", "l"), + ("м", "m"), + ("н", "n"), + ("о", "o"), + ("п", "p"), + ("р", "r"), + ("с", "s"), + ("т", "t"), + ("у", "u"), + ("ф", "f"), + ("х", "kh"), + ("ц", "ts"), + ("ч", "ch"), + ("ш", "sh"), + ("щ", "shch"), + ("ъ", "ie"), + ("ы", "y"), + ("ь", "'"), + ("э", "e"), + ("ю", "iu"), + ("я", "ia"), + ("№", "#"), + ].iter() + .cloned() + .collect() +} + +fn table_from_latin() -> CharsMapping { + [ + ("А", "A"), + ("Б", "B"), + ("В", "V"), + ("В", "W"), + ("Г", "G"), + ("Д", "D"), + ("Дж", "J"), + ("Э", "E"), + ("Ё", "Yo"), + ("Ж", "Zh"), + ("З", "Z"), + ("З", "Th"), + ("Зэ", "The"), + ("И", "I"), + ("Й", "I"), + ("К", "C"), + ("К", "K"), + ("К", "Q"), + ("К", "Ck"), + ("Кс", "X"), + ("Л", "L"), + ("М", "M"), + ("Н", "N"), + ("О", "O"), + ("Оу", "Ow"), + ("П", "P"), + ("Р", "R"), + ("С", "S"), + ("Т", "T"), + ("У", "U"), + ("Ф", "F"), + ("Х", "Kh"), + ("Х", "H"), + ("Ц", "Ts"), + ("Ч", "Ch"), + ("Ш", "Sh"), + ("Щ", "Shch"), + ("Ъ", "Ie"), + ("Ы", "Y"), + ("Ь", "'"), + ("Е", "E"), + ("Ю", "Iu"), + ("Я", "Ia"), + ("а", "a"), + ("б", "b"), + ("в", "v"), + ("в", "w"), + ("г", "g"), + ("д", "d"), + ("дж", "j"), + ("е", "e"), + ("ё", "yo"), + ("ж", "zh"), + ("з", "z"), + ("з", "th"), + ("зэ", "the"), + ("и", "i"), + ("й", "i"), + ("к", "c"), + ("к", "k"), + ("к", "q"), + ("к", "ck"), + ("кс", "x"), + ("л", "l"), + ("м", "m"), + ("н", "n"), + ("о", "o"), + ("оу", "ow"), + ("п", "p"), + ("р", "r"), + ("с", "s"), + ("т", "t"), + ("у", "u"), + ("ф", "f"), + ("х", "kh"), + ("х", "h"), + ("ц", "ts"), + ("ч", "ch"), + ("ш", "sh"), + ("щ", "shch"), + ("ъ", "ie"), + ("ы", "y"), + ("ь", "'"), + ("э", "e"), + ("ю", "iu"), + ("я", "ia"), + ("№", "#"), + ].iter() + .cloned() + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn text_test() { + let result = cyr_to_latin("Съешь же ещё этих мягких французских булок, да выпей чаю!"); + assert_eq!(result, "Sieesh' zhe eshchyo etikh miagkikh frantsuzskikh bulok, da vypei chaiu!"); + + let result2 = cyr_to_latin("Привет мир! Hello world!"); + assert_eq!(result2, "Privet mir! Hello world!"); + + let result3 = latin_to_cyr("Privet mir! Hello world! Zhypyr perotin kuroden."); + assert_eq!(result3, "Привет мир! Хелло ворлд! Жыпыр перотин куроден."); + + let result4 = latin_to_cyr("Привет мир! Hello world!"); + assert_eq!(result4, "Привет мир! Хелло ворлд!"); + + let result5 = latin_to_cyr("The quick brown fox jumps over the lazy dog!"); + assert_eq!(result5, "Зэ куик броун фокс джумпс овер зэ лазы дог!"); + } +}