albhed/lib.rs
1//! A translator for the Al Bhed language.
2//!
3//! Al Bhed is the language spoken by the Al Bhed people in the land of Spira,
4//! the main setting of the game Final Fantasy X.
5//!
6//! This library doesn't attempt to detect English loanwords that are present in
7//! Al Bhed at the time of the game, as in airship/fiend/etc.
8//!
9//! # Usage
10//!
11//! Converting Al Bhed into English:
12//! ```
13//! let al_bhed = "Oui yvnyet uv dra cay?";
14//! let english = al_bhed.chars().filter_map(albhed::from_al_bhed).collect::<String>();
15//! assert_eq!("You afraid of the sea?", english);
16//! ```
17//!
18//! Converting English into Al Bhed:
19//! ```
20//! let english = "Beware of Sandstorms!";
21//! let al_bhed = english.chars().filter_map(albhed::to_al_bhed).collect::<String>();
22//! assert_eq!("Pafyna uv Cyhtcdunsc!", al_bhed);
23//! ```
24
25#![doc(html_root_url = "https://docs.rs/albhed/0.1.0")]
26
27/// The ordering that Al Bhed letters map into English. For instance, `A` in Al
28/// Bhed maps to the English `E`.
29const AL_BHED: [char; 26] = [
30 'E', 'P', 'S', 'T', 'I', 'W', 'K', 'N', 'U', 'V', 'G', 'C', 'L', 'R', 'Y', 'B', 'X', 'H', 'M',
31 'D', 'O', 'F', 'Z', 'Q', 'A', 'J',
32];
33
34/// The ordering that English letters map into Al Bhed. For instance, `Y` in Al
35/// Bhed maps to the English `A`.
36const ENGLISH: [char; 26] = [
37 'Y', 'P', 'L', 'T', 'A', 'V', 'K', 'R', 'E', 'Z', 'G', 'M', 'S', 'H', 'U', 'B', 'X', 'N', 'C',
38 'D', 'I', 'J', 'F', 'Q', 'O', 'W',
39];
40
41/// Convert a single `char` from Al Bhed into English.
42pub fn from_al_bhed(c: char) -> Option<char> {
43 work(&AL_BHED, c)
44}
45
46/// Convert a single `char` from English into Al Bhed.
47pub fn to_al_bhed(c: char) -> Option<char> {
48 work(&ENGLISH, c)
49}
50
51fn work(table: &[char; 26], c: char) -> Option<char> {
52 match c {
53 _ if c.is_ascii_whitespace() || c.is_ascii_digit() || c.is_ascii_punctuation() => Some(c),
54 _ if c.is_ascii_alphabetic() => {
55 let index: usize = (c.to_digit(36).unwrap() - 10) as usize;
56 let trans = table[index];
57 if c.is_ascii_lowercase() {
58 Some(trans.to_ascii_lowercase())
59 } else {
60 Some(trans)
61 }
62 }
63 _ => None,
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn conversions() {
73 let pairs = vec![
74 ("Fryd ec drec?", "What is this?"),
75 ("Fa gemm ed?", "We kill it?"),
76 ("E vunpet ed!", "I forbid it!"),
77 ("Cunno.", "Sorry."),
78 ];
79
80 pairs.into_iter().for_each(|(ab, eng)| {
81 let al_bhed: String = ab.chars().filter_map(from_al_bhed).collect();
82 assert_eq!(eng, al_bhed);
83
84 let english: String = eng.chars().filter_map(to_al_bhed).collect();
85 assert_eq!(ab, english);
86 });
87 }
88}