diff --git a/src/anybase.rs b/src/anybase.rs index 8b13789..0e208dc 100644 --- a/src/anybase.rs +++ b/src/anybase.rs @@ -1 +1,82 @@ +use crate::core; +pub fn alphabet() -> Vec<String> { + return vec![ + "meow", "mrrp", "mreow", "mrow", "nya~", "nyaaaa~", "mraow", "mew", "prrp", "mewo", + "purrrr", "nya", + ] + .into_iter() + .map(|a| a.to_string()) + .collect(); +} + +pub fn max_base() -> u32 { + return alphabet().len() as u32; +} + +/// Returns the minimum catspeak words per character needed for this base +pub fn char_length(base: u32) -> u32 { + for i in 1..base + 1 { + let num = base.pow(i); + if num > 26 { + return num; + } + } + return u32::MAX; +} + +/// Encodes text into catspeak using any base up to [`max_base()`] +/// +/// `char_length` is set manually, but the minimum can be generated using [`char_length()`] +/// +/// ``` +/// use cat2text::anybase; +/// let text = "i love cats".to_string(); +/// let base = 10; +/// let char_length = anybase::char_length(base); +/// +/// assert_eq!("", anybase::encode(text, base, char_length)); +/// ``` +pub fn encode(text: String, base: u32, char_length: u32) -> String { + let mut shortened_alphabet = alphabet(); + shortened_alphabet.truncate(base as usize); + + // makes it lowercase and split by spaces + let words: Vec<String> = text + .to_ascii_lowercase() + .split(" ") + .map(|item| return item.to_string()) + .collect(); + let mut words_as_bytes: Vec<Vec<u8>> = Vec::new(); + for word in words { + // convert to bytes then subtract by 96 + words_as_bytes.push(word.as_bytes().into_iter().map(|item| item - 96).collect()); + } + + let mut results: Vec<Vec<String>> = Vec::new(); + for i in 0..words_as_bytes.len() { + results.push(Vec::new()); + for j in 0..words_as_bytes[i].len() { + results[i].push(core::num_to_cat( + words_as_bytes[i][j] as u32, + shortened_alphabet.clone(), + char_length, + )); + } + } + + let results: Vec<String> = results.into_iter().map(|item| item.join(" ")).collect(); + let results = results.join("; "); + return results; +} + + +#[test] +fn test_anybase_encode() { + use crate::anybase; + let text = "i love cats".to_string(); + let base = 10; + let char_length = anybase::char_length(base); + + assert_eq!("", anybase::encode(text, base, char_length)); +}