summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs313
-rw-r--r--src/main.rs26
2 files changed, 339 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..0e3e482
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,313 @@
+use std::borrow::Cow;
+
+use lazy_static::lazy_static;
+use regex::Regex;
+
+fn to_title_case<'a>(text: &'a str) -> Cow<'a, str> {
+ let mut chars = text.chars();
+ match chars.next() {
+ None => Cow::Borrowed(text),
+ Some(c) => Cow::Owned(
+ c.to_uppercase().collect::<String>() +
+ &chars.as_str().to_lowercase()
+ )
+ }
+}
+
+lazy_static! {
+ static ref FACE_RE: Regex = Regex::new(r"[:Xx][\)\]|p|P|d|D|o|O]").unwrap();
+}
+
+trait Trollify {
+ fn sentance_delimiter(&self) -> char {
+ '.'
+ }
+
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Borrowed(word)
+ }
+
+ fn troll_line<'l>(&self, line: &'l str) -> Cow<'l, str> {
+ Cow::Borrowed(line)
+ }
+
+ fn troll_sentence<'s>(&self, sentence: &'s str) -> Cow<'s, str> {
+ Cow::Borrowed(sentence)
+ }
+
+ fn troll_all<'a>(&self, all: &'a str) -> Cow<'a, str> {
+ Cow::Borrowed(all)
+ }
+
+ fn troll_face<'f>(&self, face: &'f str) -> Cow<'f, str> {
+ Cow::Borrowed(face)
+ }
+}
+
+struct Araida;
+
+impl Trollify for Araida {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word.to_lowercase().replace("o", "0"))
+ }
+}
+
+struct Tavros;
+
+impl Trollify for Tavros {
+ fn sentance_delimiter(&self) -> char {
+ ','
+ }
+
+ fn troll_sentence<'s>(&self, sentence: &'s str) -> Cow<'s, str> {
+ let mut chars = sentence.chars();
+ match chars.next() {
+ None => Cow::Borrowed(sentence),
+ Some(c) => Cow::Owned(
+ c.to_lowercase().collect::<String>() +
+ &chars.as_str().to_uppercase()
+ )
+ }
+ }
+
+ fn troll_all<'a>(&self, all: &'a str) -> Cow<'a, str> {
+ Cow::Owned(all
+ .replace(".", ",")
+ .replace("?", ",")
+ .replace("!", ",")
+ )
+ }
+
+ fn troll_face<'f>(&self, face: &'f str) -> Cow<'f, str> {
+ Cow::Owned(String::from("}") + face)
+ }
+}
+
+struct Sollux;
+
+impl Trollify for Sollux {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word
+ .to_lowercase()
+ .replace("s", "2")
+ .replace("i", "ii")
+ .replace("to", "two")
+ )
+ }
+}
+
+struct Karkat;
+
+impl Trollify for Karkat {
+ fn troll_all<'a>(&self, all: &'a str) -> Cow<'a, str> {
+ Cow::Owned(all.to_uppercase())
+ }
+}
+
+struct Nepeta;
+
+impl Trollify for Nepeta {
+ fn troll_line<'l>(&self, line: &'l str) -> Cow<'l, str> {
+ Cow::Owned(
+ String::from(":33 < ") +
+ &line.to_lowercase()
+ )
+ }
+}
+
+struct Kanaya;
+
+impl Trollify for Kanaya {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ to_title_case(word)
+ }
+}
+
+struct Terezi;
+
+impl Trollify for Terezi {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word
+ .to_uppercase()
+ .replace("A", "4")
+ .replace("I", "1")
+ .replace("E", "3")
+ )
+ }
+
+ fn troll_face<'f>(&self, face: &'f str) -> Cow<'f, str> {
+ Cow::Owned(
+ String::from(">") +
+ &face.replace(")", "]")
+ )
+ }
+}
+
+struct Vriska;
+
+impl Trollify for Vriska {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word.replace("b", "8"))
+ }
+
+ fn troll_sentence<'s>(&self, sentence: &'s str) -> Cow<'s, str> {
+ to_title_case(sentence)
+ }
+
+ fn troll_face<'f>(&self, face: &'f str) -> Cow<'f, str> {
+ Cow::Owned(face
+ .replace(":", "::::")
+ .replace("X", "XXXX")
+ )
+ }
+}
+
+struct Equius;
+
+impl Trollify for Equius {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word.replace("x", "%"))
+ }
+
+ fn troll_sentence<'s>(&self, sentence: &'s str) -> Cow<'s, str> {
+ to_title_case(sentence)
+ }
+
+ fn troll_line<'l>(&self, line: &'l str) -> Cow<'l, str> {
+ Cow::Owned(String::from("D --> ") + line)
+ }
+}
+
+struct Gamzee;
+
+impl Trollify for Gamzee {
+ fn troll_all<'a>(&self, all: &'a str) -> Cow<'a, str> {
+ let chars = all.chars();
+ let mut next = true;
+ let mut buf = String::new();
+ for char in chars {
+ if char.is_alphabetic() {
+ if next {
+ buf += &char.to_uppercase().to_string();
+ } else {
+ buf += &char.to_lowercase().to_string();
+ }
+ next = !next;
+ } else {
+ buf.push(char);
+ }
+ }
+ Cow::Owned(buf)
+ }
+
+ fn troll_face<'f>(&self, face: &'f str) -> Cow<'f, str> {
+ Cow::Owned(face.replace(":", ":o"))
+ }
+}
+
+struct Eridan;
+
+impl Trollify for Eridan {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word
+ .to_lowercase()
+ .replace("v", "vv")
+ .replace("w", "ww")
+ )
+ }
+}
+
+struct Feferi;
+
+impl Trollify for Feferi {
+ fn troll_word<'w>(&self, word: &'w str) -> Cow<'w, str> {
+ Cow::Owned(word
+ .replace("h", ") (")
+ .replace("E", "-E")
+ )
+ }
+
+ fn troll_sentence<'s>(&self, sentence: &'s str) -> Cow<'s, str> {
+ to_title_case(sentence)
+ }
+
+ fn troll_face<'f>(&self, face: &'f str) -> Cow<'f, str> {
+ Cow::Owned(face.replace(":", "3:"))
+ }
+}
+
+#[derive(clap::ValueEnum, serde::Serialize, Clone, Copy, Debug)]
+#[serde(rename_all = "kebab-case")]
+pub enum Troll {
+ Araida,
+ Tavros,
+ Sollux,
+ Karkat,
+ Nepeta,
+ Kanaya,
+ Terezi,
+ Vriska,
+ Equius,
+ Gamzee,
+ Eridan,
+ Feferi
+}
+
+fn get_troll(troll: Troll) -> Box<dyn Trollify> {
+ match troll {
+ Troll::Araida => Box::new(Araida {}),
+ Troll::Tavros => Box::new(Tavros {}),
+ Troll::Sollux => Box::new(Sollux {}),
+ Troll::Karkat => Box::new(Karkat {}),
+ Troll::Nepeta => Box::new(Nepeta {}),
+ Troll::Kanaya => Box::new(Kanaya {}),
+ Troll::Terezi => Box::new(Terezi {}),
+ Troll::Vriska => Box::new(Vriska {}),
+ Troll::Equius => Box::new(Equius {}),
+ Troll::Gamzee => Box::new(Gamzee {}),
+ Troll::Eridan => Box::new(Eridan {}),
+ Troll::Feferi => Box::new(Feferi {}),
+ }
+}
+
+pub fn trollify<'a>(text: &'a str, troll: Troll) -> String {
+ let troll = get_troll(troll);
+
+ let text = troll.troll_all(text);
+ let sentences = text.split(troll.sentance_delimiter());
+ let mut buf = String::new();
+ for sentence in sentences {
+ let sentence = troll.troll_sentence(sentence);
+ sentence
+ .split(" ")
+ .into_iter()
+ .map(|word| {
+ match FACE_RE.is_match(word) {
+ true => troll.troll_face(word),
+ false => troll.troll_word(word)
+ }
+ })
+ .enumerate()
+ .for_each(|(idx, word)| {
+ if idx != 0 {
+ buf += " ";
+ }
+ buf += &word;
+ });
+ }
+ let text = buf;
+
+ let lines = text.split("\n");
+ let mut buf = String::new();
+ for (idx, line) in lines.enumerate() {
+ if idx != 0 {
+ buf.push('\n');
+ }
+ let line = troll.troll_line(line);
+ buf += &line;
+ }
+ let text = buf;
+
+ text
+}
+
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..30d17b1
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,26 @@
+use std::io;
+use clap::Parser;
+use trollify::{trollify, Troll};
+
+#[derive(Parser, Debug)]
+#[command(version, about, long_about = None)]
+struct Args {
+ troll: Troll
+}
+
+fn main() {
+ let args = Args::parse();
+
+ let mut line = String::new();
+ loop {
+ match io::stdin().read_line(&mut line) {
+ Ok(0) => break,
+ Err(_) => break,
+ Ok(_) => {
+ let out = trollify(&line, args.troll);
+ print!("{}", out);
+ line.clear();
+ },
+ }
+ }
+}