diff options
author | Freya Murphy <freya@freyacat.org> | 2024-04-18 13:26:17 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-04-18 13:26:17 -0400 |
commit | 125fd67c96196ba77ea802f26d64acb4e13ddea7 (patch) | |
tree | 3b5ed42d9e479bdf22e9f230e8dddb78c56defbc /src | |
download | trollify-main.tar.gz trollify-main.tar.bz2 trollify-main.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 313 | ||||
-rw-r--r-- | src/main.rs | 26 |
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(); + }, + } + } +} |