commit 91dbec05d3278c177b8c647218680f1b5248ca63
Author: askiiart <dev@askiiart.net>
Date:   Sat Jan 11 23:20:00 2025 -0600

    half-functional prototype

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..bef8f31
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "cat2text"
+version = "0.1.0"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..e5b08e5
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "cat2text"
+version = "0.1.0"
+edition = "2021"
+license = "GPL-3.0-or-later"
+repository = "https://git.askiiart.net/askiiart/cat2text-rs"
+
+[lib]
+name = "cat2text"
+path = "src/lib.rs"
+
+[[bin]]
+name = "cat2text"
+path = "src/main.rs"
+
+[dependencies]
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..8562ca0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Cat2Text-rs
+
+This is a port of [Cat2Text](https://github.com/askiiart/Cat2Text) to Rust, with extra functionality, better documentation, and support for using it as a library as well.
diff --git a/src/base4.rs b/src/base4.rs
new file mode 100644
index 0000000..4028aba
--- /dev/null
+++ b/src/base4.rs
@@ -0,0 +1,49 @@
+/*
+def decode(string):
+    """Decode a Base 4 encoded string into the number
+    Arguments:
+    - `string`: The encoded string
+    - `alphabet`: The alphabet to use for decoding
+    """
+    base = len(alphabet)
+    strlen = len(string)
+    num = 0
+
+    idx = 0
+    for char in string:
+        power = (strlen - (idx + 1))
+        num += alphabet.index(char) * (base ** power)
+        idx += 1
+
+    return num
+ */
+
+pub fn alphabet() -> Vec<String> {
+    return vec!["meow", "mrrp", "mreow", "mrow"]
+        .into_iter()
+        .map(|a| a.to_string())
+        .collect();
+}
+
+/// How many words long a character is when translated to catspeak
+pub fn char_length() -> u32 {
+    return 3;
+}
+
+// TODO: Add uppercase support, maybe possible?
+pub fn encode(text: String) {
+    // 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 translation: String = "".to_string();
+    for word in words_as_bytes {}
+}
diff --git a/src/core.rs b/src/core.rs
new file mode 100644
index 0000000..c15883b
--- /dev/null
+++ b/src/core.rs
@@ -0,0 +1,50 @@
+//! Handles conversion one word at a time for any base
+
+use std::ops::Index;
+
+use crate::base4::alphabet;
+
+pub fn num_to_cat(num: u32, alphabet: Vec<String>, char_length: u32) -> String {
+    let mut num: u32 = num.clone();
+    let base: u32 = alphabet.len() as u32;
+
+    // base*n*-ifying logic
+    let mut nums: Vec<u32> = Vec::new();
+    while (nums.len() as u32) < char_length {
+        nums.push((num as u32) % base);
+        num /= base;
+    }
+    nums.reverse();
+
+    let mut result = "".to_string();
+    for i in nums.clone() {
+        result += alphabet[i as usize].as_str();
+        // put a space in between if it's not the last one
+        if i != nums.len() as u32 - 1 {
+            result += " "
+        }
+    }
+
+    return result;
+}
+
+/// Converts catspeak to a [`u32`]
+pub fn cat_to_num(text: Vec<String>, alphabet: Vec<String>, char_length: u32) -> u32 {
+    let mut nums: Vec<u32> = Vec::new();
+    for word in text.clone() {
+        for i in 0..alphabet.len() {
+            if word == alphabet[i] {
+                nums.push(i as u32);
+            }
+        }
+    }
+
+    let base = alphabet.len();
+    let idx = 0;
+    let mut num = 0 as u32;
+    for n in nums {
+        let power = (text.len() - (idx + 1)) as u32;
+        num += n * (base as u32).pow(power);
+    }
+    return num;
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..9eb186e
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,5 @@
+//! # Cat2Text-rs
+//!
+//! This is a port of [Cat2Text](https://github.com/askiiart/Cat2Text) to Rust, with extra functionality, better documentation, and support for using it as a library as well.
+pub mod base4;
+pub mod core;
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..8de31c4
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,44 @@
+extern crate cat2text;
+use cat2text::{base4, core};
+use std::{io, process::exit};
+
+fn main() {
+    let stdin = io::stdin();
+    let mut input = String::new();
+
+    loop {
+        println!("Pick your translation:");
+        println!("1) cat to text");
+        println!("2) text to cat");
+        input = "".to_string();
+        stdin.read_line(&mut input).unwrap();
+        let trimmed = input.trim();
+        if trimmed == "1".to_string() {
+            input = "".to_string();
+            stdin.read_line(&mut input).unwrap();
+            println!(
+                "{}",
+                core::cat_to_num(
+                    input.trim().to_string().split(" ").into_iter().map(|item| item.to_string()).collect(),
+                    base4::alphabet(),
+                    base4::char_length()
+                )
+            )
+        } else if trimmed == "2".to_string() {
+            input = "".to_string();
+            stdin.read_line(&mut input).unwrap();
+            println!(
+                "{}",
+                core::num_to_cat(
+                    input.trim().parse().unwrap(),
+                    base4::alphabet(),
+                    base4::char_length()
+                )
+            )
+        } else {
+            println!("Invalid input, exiting...");
+            break;
+        }
+        println!();
+    }
+}