Compare commits
4 commits
9bcfd8d2e5
...
4ceb59d052
Author | SHA1 | Date | |
---|---|---|---|
|
4ceb59d052 | ||
|
da155441f9 | ||
|
bf1c17b8f9 | ||
|
5bf2d3670f |
5 changed files with 81 additions and 58 deletions
|
@ -66,3 +66,4 @@ This currently only supports lowercase text in the latin alphabet, and byte arra
|
||||||
- Improve CLI
|
- Improve CLI
|
||||||
- Add error handling
|
- Add error handling
|
||||||
- Do `AsRef` stuff
|
- Do `AsRef` stuff
|
||||||
|
- Add u16/2-byte encoding in addition to just u8 for greater efficiency
|
||||||
|
|
|
@ -1,52 +1,21 @@
|
||||||
|
//! This module translates text
|
||||||
use crate::core;
|
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
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use cat2text::anybase::char_length;
|
|
||||||
///
|
|
||||||
/// let base = 10;
|
|
||||||
/// assert_eq!(char_length(base), 2)
|
|
||||||
/// ```
|
|
||||||
pub fn char_length(base: u32) -> u32 {
|
|
||||||
for i in 1..base + 1 {
|
|
||||||
let num = base.pow(i);
|
|
||||||
if num > 26 {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return u32::MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Encodes text into catspeak using any base up to [`max_base()`]
|
/// 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()`]
|
/// `char_length` is set manually, but the minimum can be generated using [`char_length()`]
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use cat2text::anybase;
|
/// use cat2text::{anybase::encode, core::char_length};
|
||||||
///
|
///
|
||||||
/// let text = "i love cats".to_string();
|
/// let text = "i love cats".to_string();
|
||||||
/// let base = 10;
|
/// let base = 10;
|
||||||
/// let char_length = anybase::char_length(base);
|
/// let char_length = char_length(base);
|
||||||
///
|
///
|
||||||
/// assert_eq!("meow mewo; mrrp mreow mrrp nyaaaa~ mreow mreow meow nyaaaa~; meow mrow meow mrrp mreow meow mrrp mewo", anybase::encode(text, base, char_length));
|
/// assert_eq!("meow mewo; mrrp mreow mrrp nyaaaa~ mreow mreow meow nyaaaa~; meow mrow meow mrrp mreow meow mrrp mewo", encode(text, base, char_length));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn encode(text: String, base: u32, char_length: u32) -> String {
|
pub fn encode(text: String, base: u32, char_length: u32) -> String {
|
||||||
let mut shortened_alphabet = alphabet();
|
let mut shortened_alphabet = core::alphabet();
|
||||||
shortened_alphabet.truncate(base as usize);
|
shortened_alphabet.truncate(base as usize);
|
||||||
|
|
||||||
// makes it lowercase and split by spaces
|
// makes it lowercase and split by spaces
|
||||||
|
@ -83,18 +52,18 @@ pub fn encode(text: String, base: u32, char_length: u32) -> String {
|
||||||
/// `char_length` is set manually, but the minimum can be generated using [`char_length()`]
|
/// `char_length` is set manually, but the minimum can be generated using [`char_length()`]
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use cat2text::anybase;
|
/// use cat2text::{anybase::decode, core::char_length};
|
||||||
///
|
///
|
||||||
/// let text = "meow mewo; mrrp mreow mrrp nyaaaa~ mreow mreow meow nyaaaa~; meow mrow meow mrrp mreow meow mrrp mewo".to_string();
|
/// let text = "meow mewo; mrrp mreow mrrp nyaaaa~ mreow mreow meow nyaaaa~; meow mrow meow mrrp mreow meow mrrp mewo".to_string();
|
||||||
/// let base = 10;
|
/// let base = 10;
|
||||||
/// let char_length = anybase::char_length(base);
|
/// let char_length = char_length(base);
|
||||||
|
|
||||||
/// assert_eq!("i love cats", anybase::decode(text, base, char_length));
|
/// assert_eq!("i love cats", decode(text, base, char_length));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn decode(text: String, base: u32, char_length: u32) -> String {
|
pub fn decode(text: String, base: u32, char_length: u32) -> String {
|
||||||
let catspeak_words: Vec<String> = text.split("; ").map(|item| item.to_string()).collect();
|
let catspeak_words: Vec<String> = text.split("; ").map(|item| item.to_string()).collect();
|
||||||
let mut output: String = String::new();
|
let mut output: String = String::new();
|
||||||
let mut shortened_alphabet = alphabet();
|
let mut shortened_alphabet = core::alphabet();
|
||||||
shortened_alphabet.truncate(base as usize);
|
shortened_alphabet.truncate(base as usize);
|
||||||
for engl_word in catspeak_words {
|
for engl_word in catspeak_words {
|
||||||
let mut word = String::new();
|
let mut word = String::new();
|
||||||
|
@ -118,12 +87,11 @@ pub fn decode(text: String, base: u32, char_length: u32) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod bytes {
|
pub mod bytes {
|
||||||
use super::alphabet;
|
|
||||||
use crate::core;
|
use crate::core;
|
||||||
/// Encodes from bytes into catspeak
|
/// Encodes from bytes into catspeak
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use cat2text::anybase::{bytes::encode, char_length};
|
/// use cat2text::{anybase::bytes::encode, core::char_length};
|
||||||
///
|
///
|
||||||
/// let bytes = &[9, 1];
|
/// let bytes = &[9, 1];
|
||||||
/// let base = 10;
|
/// let base = 10;
|
||||||
|
@ -133,7 +101,7 @@ pub mod bytes {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn encode(bytes: impl AsRef<[u8]>, base: u32, char_length: u32) -> String {
|
pub fn encode(bytes: impl AsRef<[u8]>, base: u32, char_length: u32) -> String {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
let mut shortened_alphabet = alphabet();
|
let mut shortened_alphabet = core::alphabet();
|
||||||
shortened_alphabet.truncate(base as usize);
|
shortened_alphabet.truncate(base as usize);
|
||||||
for byte in bytes.as_ref() {
|
for byte in bytes.as_ref() {
|
||||||
output += core::num_to_cat(*byte as u32, shortened_alphabet.clone(), char_length).as_str();
|
output += core::num_to_cat(*byte as u32, shortened_alphabet.clone(), char_length).as_str();
|
||||||
|
@ -145,7 +113,7 @@ pub mod bytes {
|
||||||
/// Decodes catspeak into bytes
|
/// Decodes catspeak into bytes
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use cat2text::anybase::{bytes::decode, char_length};
|
/// use cat2text::{anybase::bytes::decode, core::char_length};
|
||||||
///
|
///
|
||||||
/// let text = "mreow mrrp meow mrrp".to_string();
|
/// let text = "mreow mrrp meow mrrp".to_string();
|
||||||
/// let base = 10;
|
/// let base = 10;
|
||||||
|
@ -158,7 +126,7 @@ pub mod bytes {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn decode(text: String, base: u32, char_length: u32) -> Vec<u8> {
|
pub fn decode(text: String, base: u32, char_length: u32) -> Vec<u8> {
|
||||||
let mut output: Vec<u8> = Vec::new();
|
let mut output: Vec<u8> = Vec::new();
|
||||||
let mut shortened_alphabet = alphabet();
|
let mut shortened_alphabet = core::alphabet();
|
||||||
shortened_alphabet.truncate(base as usize);
|
shortened_alphabet.truncate(base as usize);
|
||||||
for byte in core::split_every_x(text.clone(), char_length) {
|
for byte in core::split_every_x(text.clone(), char_length) {
|
||||||
output.push(core::cat_to_num(
|
output.push(core::cat_to_num(
|
||||||
|
@ -170,3 +138,4 @@ pub mod bytes {
|
||||||
return output.into();
|
return output.into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ...
|
13
src/base4.rs
13
src/base4.rs
|
@ -1,12 +1,15 @@
|
||||||
|
//! This module handles base 4, like the original [Cat2Text](https://github.com/Evelyn3440/Cat2Text); it can translate either english text a-z, or byte arrays (see [`bytes`])
|
||||||
|
use crate::core;
|
||||||
use crate::anybase;
|
use crate::anybase;
|
||||||
|
|
||||||
|
/// Returns the alphabet used by `cat2text::base4`
|
||||||
pub fn alphabet() -> Vec<String> {
|
pub fn alphabet() -> Vec<String> {
|
||||||
let mut tmp = anybase::alphabet();
|
let mut tmp = core::alphabet();
|
||||||
tmp.truncate(4);
|
tmp.truncate(4);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How many words long a character is when translated to catspeak
|
/// How many words long an english character is when translated to catspeak
|
||||||
pub fn char_length() -> u32 {
|
pub fn char_length() -> u32 {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +38,7 @@ pub fn decode(text: String) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod bytes {
|
pub mod bytes {
|
||||||
|
//! This handles encoding and decoding bytes to/from catspeak
|
||||||
use crate::anybase;
|
use crate::anybase;
|
||||||
use super::char_length;
|
use super::char_length;
|
||||||
/// Encodes from bytes into catspeak
|
/// Encodes from bytes into catspeak
|
||||||
|
@ -42,7 +46,7 @@ pub mod bytes {
|
||||||
/// ```
|
/// ```
|
||||||
/// use cat2text::base4::bytes::encode;
|
/// use cat2text::base4::bytes::encode;
|
||||||
///
|
///
|
||||||
/// assert_eq!("meow meow mreow mrrp meow meow meow mrrp", encode(&[9, 1]));
|
/// assert_eq!("meow mreow mrrp meow meow mrrp", encode(&[9, 1]));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn encode(bytes: impl AsRef<[u8]>) -> String {
|
pub fn encode(bytes: impl AsRef<[u8]>) -> String {
|
||||||
anybase::bytes::encode(bytes, 4, char_length())
|
anybase::bytes::encode(bytes, 4, char_length())
|
||||||
|
@ -53,10 +57,9 @@ pub mod bytes {
|
||||||
/// ```
|
/// ```
|
||||||
/// use cat2text::base4::bytes::decode;
|
/// use cat2text::base4::bytes::decode;
|
||||||
///
|
///
|
||||||
/// assert_eq!(vec![9, 1], decode("meow meow mreow mrrp meow meow meow mrrp".to_string()));
|
/// assert_eq!(vec![9, 1], decode("meow mreow mrrp meow meow mrrp".to_string()));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn decode(text: String) -> Vec<u8> {
|
pub fn decode(text: String) -> Vec<u8> {
|
||||||
anybase::bytes::decode(text, 4, char_length())
|
anybase::bytes::decode(text, 4, char_length())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ..............d......4..............a.q..a....y..d..w...a............
|
|
58
src/core.rs
58
src/core.rs
|
@ -58,14 +58,16 @@ pub fn cat_to_num(text: Vec<String>, alphabet: Vec<String>, char_length: u32) ->
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Splits a cat word into every x segments
|
/// Splits a word encoded in catspeak every *x* segments
|
||||||
///
|
///
|
||||||
/// ```
|
/// Used for decoding by splitting words apart into letters which can then be decoded individually
|
||||||
|
///
|
||||||
|
/// ```ignore
|
||||||
/// use cat2text::core::split_every_x;
|
/// use cat2text::core::split_every_x;
|
||||||
///
|
///
|
||||||
/// assert_eq!(vec!["meow meow mrrp".to_string(), "meow mreow mrrp".to_string(), "mreow meow mrrp".to_string()], split_every_x("meow meow mrrp meow mreow mrrp mreow meow mrrp".to_string(), 3));
|
/// assert_eq!(vec!["meow meow mrrp".to_string(), "meow mreow mrrp".to_string()], split_every_x("meow meow mrrp meow mreow mrrp".to_string(), 3));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn split_every_x(text: String, x: u32) -> Vec<String> {
|
pub(crate) fn split_every_x(text: String, x: u32) -> Vec<String> {
|
||||||
let x = x as usize;
|
let x = x as usize;
|
||||||
let delim = " ";
|
let delim = " ";
|
||||||
let tmp: Vec<String> = text.split(delim).map(|item| item.to_string()).collect();
|
let tmp: Vec<String> = text.split(delim).map(|item| item.to_string()).collect();
|
||||||
|
@ -82,3 +84,51 @@ pub fn split_every_x(text: String, x: u32) -> Vec<String> {
|
||||||
output = output.into_iter().map(|item| item.trim().to_string()).collect();
|
output = output.into_iter().map(|item| item.trim().to_string()).collect();
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns all cat sounds in the catspeak alphabet
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use cat2text::core::alphabet;
|
||||||
|
///
|
||||||
|
/// println!("{:?}", alphabet());
|
||||||
|
/// ```
|
||||||
|
pub fn alphabet() -> Vec<String> {
|
||||||
|
return vec![
|
||||||
|
"meow", "mrrp", "mreow", "mrow", "nya~", "nyaaaa~", "mraow", "mew", "prrp", "mewo",
|
||||||
|
"purrrr", "nya", "miao", "miau", "miauw", "mrow~"
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.map(|a| a.to_string())
|
||||||
|
.collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the max base that can be used
|
||||||
|
///
|
||||||
|
/// For example, if the available alphabet was `["meow", "mrrp", "mreow", "mrow"]`, the max base would be 4
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use cat2text::core::max_base;
|
||||||
|
///
|
||||||
|
/// println!("{}", max_base());
|
||||||
|
/// ```
|
||||||
|
pub fn max_base() -> u32 {
|
||||||
|
return alphabet().len() as u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the minimum catspeak words per character needed for this base
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use cat2text::core::char_length;
|
||||||
|
///
|
||||||
|
/// let base = 10;
|
||||||
|
/// assert_eq!(char_length(base), 2)
|
||||||
|
/// ```
|
||||||
|
pub fn char_length(base: u32) -> u32 {
|
||||||
|
for i in 1..base + 1 {
|
||||||
|
let num = base.pow(i);
|
||||||
|
if num > 26 {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return u32::MAX;
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
#[test]
|
#[test]
|
||||||
fn test_anybase_base4() {
|
fn test_anybase_base4() {
|
||||||
use crate::{anybase, base4};
|
use crate::{anybase, base4, core};
|
||||||
let text = "i love cats".to_string();
|
let text = "i love cats".to_string();
|
||||||
|
|
||||||
let encoded = anybase::encode(text.clone(), 4, anybase::char_length(4));
|
let encoded = anybase::encode(text.clone(), 4, core::char_length(4));
|
||||||
assert_eq!(base4::encode(text), encoded);
|
assert_eq!(base4::encode(text), encoded);
|
||||||
|
|
||||||
let decoded = anybase::decode(encoded.clone(), 4, anybase::char_length(4));
|
let decoded = anybase::decode(encoded.clone(), 4, core::char_length(4));
|
||||||
assert_eq!(base4::decode(encoded), decoded);
|
assert_eq!(base4::decode(encoded), decoded);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue