diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3fd3deb..9117847 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -154,6 +154,7 @@ jobs: - uses: mislav/bump-homebrew-formula-action@v1 if: "!contains(github.ref, '-')" # skip prereleases with: + create-pullrequest: true formula-name: ${{ env.BIN }} formula-path: Formula/${{ env.BIN }}.rb homebrew-tap: sgoudham/homebrew-tap diff --git a/Cargo.toml b/Cargo.toml index 8a5ed80..3db704f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "uwuifyy" -version = "0.2.0" +version = "0.3.0" edition = "2021" -authors = ["Goudham "] +authors = ["Goudham Suresh "] description = "A robust, customizable, blazingly-fast, efficient and easy-to-use command line application to uwu'ify your text!" license = "MIT" readme = "README.md" @@ -31,7 +31,6 @@ linkify = "0.8.0" rand_xoshiro = "0.6.0" ahash = "0.7.6" memmap = "0.7.0" -kaomoji-ru = "1.0.1" [profile.release] lto = "fat" @@ -46,4 +45,4 @@ lto = "fat" codegen-units = 1 [features] -bench = [] +bench = [] \ No newline at end of file diff --git a/README.md b/README.md index 17a7d33..96a96b9 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ * [Binaries](#binaries) + [Windows](#windows) + [Linux \ macOS](#Linux-\-macOS) - + [Rust \ Cargo](#Rust-\-Cargo) + * [Rust \ Cargo](#Rust-\-Cargo) * [Usage](#usage) + [Text Input to Text Output](#text-input-to-text-output) + [Text Input to File Output](#text-input-to-file-output) @@ -138,11 +138,11 @@ $ source ~/.bash_profile 6. Verify installation ```shell -$ uwuifyy --help -uwuifyy 0.2.0 +$ uwuifyy --version +uwuifyy 0.3.0 ``` -### Rust \ Cargo +## Rust \ Cargo Alternatively, if using Rust's package manager, `Cargo`, all that is needed is @@ -162,14 +162,16 @@ USAGE: uwuifyy.exe [OPTIONS] <--text |--infile > OPTIONS: - -t, --text Text to uwu'ify + -t, --text The text to uwu'ify -i, --infile The file to uwu'ify -o, --outfile The file to output uwu'ified text + --ascii-only The uwu'ified text will only include ASCII faces + --unicode-only The uwu'ified text will only include UTF-8 faces + -r, --random The flag to enable randomized uwu'ified text -w, --words The modifier to determine how many words to be uwu'ified [default: 1] -f, --faces The modifier for uwu faces e.g hello -> hewwo [default: 0.05] -a, --actions The modifier for actions e.g *shuffles over* [default: 0.125] -s, --stutters The modifier for stutters e.g b-baka! [default: 0.225] - -r, --random Flag to enable/disable random uwu'ifying -h, --help Print help information -V, --version Print version information ``` diff --git a/src/constants.rs b/src/constants.rs index afa81fc..2c9022b 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,252 +1,204 @@ -pub const FACES_SIZE: usize = 106; -pub const FACES: [&[u8]; FACES_SIZE] = [ - b"OwO", - b"UwU", - b">w<", - b"^w^", - b"^-^", - b":3", - b"x3", - b"xDD", - b";;w;;", - b">_<", - b">_>", - b"^.^", - b":33", - b"uWu", +pub const ASCII_FACES_SIZE: usize = 33; +pub const ASCII_FACES: [&[u8]; ASCII_FACES_SIZE] = [ + b"OwO ", + b"UwU ", + b">w< ", + b"^w^ ", + b"^-^ ", + b":3 ", + b"x3 ", + b"xDD ", + b";;w;; ", + b">_< ", + b">_> ", + b"^.^ ", + b":33 ", + b"uWu ", + b"(o^ ^o) ", + b"(o-_-o) ", + b"(*^.^*) ", + b"(--_--) ", + b"o(>< )o ", + b"(-_-) ", + b"(T_T) ", + b"(>_<) ", + b"~(>_<~) ", + b"(x_x)V ", + b"(;;;*_*) ", + b"{{ (>_<) }} ", + b"(o_O) ", + b"(O_O;) ", + b"(O.O) ", + b"(o_O)! ", + b"(^-^*)/ ", + b"(o^ ^o)/ ", + b"( ~*-*)~ ", +]; + +pub const UNICODE_FACES_SIZE: usize = 66; +pub const UNICODE_FACES: [&[u8]; UNICODE_FACES_SIZE] = [ // (* ^ ω ^) - kaomoji_ru::positive_emotions::JOY[0], + b"(* ^ \xCF\x89 ^) ", // (´ ∀ ` *) - kaomoji_ru::positive_emotions::JOY[1], + b"(\xC2\xB4 \xE2\x88\x80 ` *) ", // (o^▽^o) - kaomoji_ru::positive_emotions::JOY[4], + b"(o^\xE2\x96\xBD^o) ", // (⌒▽⌒)☆ - kaomoji_ru::positive_emotions::JOY[5], - // <( ̄︶ ̄)> - kaomoji_ru::positive_emotions::JOY[6], + b"(\xE2\x8C\x92\xE2\x96\xBD\xE2\x8C\x92)\xE2\x98\x86 ", // ヽ(・∀・)ノ - kaomoji_ru::positive_emotions::JOY[8], - // (´。• ω •。`) - kaomoji_ru::positive_emotions::JOY[9], + b"\xE3\x83\xBD(\xE3\x83\xBB\xE2\x88\x80\xE3\x83\xBB)\xEF\xBE\x89 ", // ( ̄ω ̄) - kaomoji_ru::positive_emotions::JOY[10], + b"(\xEF\xBF\xA3\xCF\x89\xEF\xBF\xA3) ", // (o・ω・o) - kaomoji_ru::positive_emotions::JOY[12], - // ヽ(*・ω・)ノ - kaomoji_ru::positive_emotions::JOY[14], + b"(o\xEF\xBD\xA5\xCF\x89\xEF\xBD\xA5o) ", // (^人^) - kaomoji_ru::positive_emotions::JOY[16], + b"(^\xE4\xBA\xBA^) ", // (*´▽`*) - kaomoji_ru::positive_emotions::JOY[18], - // ( ´ ω ` ) - kaomoji_ru::positive_emotions::JOY[20], + b"(*\xC2\xB4\xE2\x96\xBD`*) ", // (≧◡≦) - kaomoji_ru::positive_emotions::JOY[22], + b"(\xE2\x89\xA7\xE2\x97\xA1\xE2\x89\xA6) ", // (o´∀`o) - kaomoji_ru::positive_emotions::JOY[23], - // (´• ω •`) - kaomoji_ru::positive_emotions::JOY[24], + b"(o\xC2\xB4\xE2\x88\x80`o) ", // (^▽^) - kaomoji_ru::positive_emotions::JOY[25], + b"(\xEF\xBC\xBE\xE2\x96\xBD\xEF\xBC\xBE') ", // (⌒ω⌒) - kaomoji_ru::positive_emotions::JOY[26], + b"(\xE2\x8C\x92\xCF\x89\xE2\x8C\x92) ", // ╰(▔∀▔)╯ - kaomoji_ru::positive_emotions::JOY[28], + b"\xE2\x95\xB0(\xE2\x96\x94\xE2\x88\x80\xE2\x96\x94)\xE2\x95\xAF ", // (*^‿^*) - kaomoji_ru::positive_emotions::JOY[30], + b"(*^\xE2\x80\xBF^*) ", // (✯◡✯) - kaomoji_ru::positive_emotions::JOY[32], + b"(\xE2\x9C\xAF\xE2\x97\xA1\xE2\x9C\xAF) ", // (*≧ω≦*) - kaomoji_ru::positive_emotions::JOY[34], + b"(*\xE2\x89\xA7\xCF\x89\xE2\x89\xA6*) ", // (☆▽☆) - kaomoji_ru::positive_emotions::JOY[35], + b"(\xE2\x98\x86\xE2\x96\xBD\xE2\x98\x86) ", // \(≧▽≦)/ - kaomoji_ru::positive_emotions::JOY[37], - // ヽ(o^▽^o)ノ - kaomoji_ru::positive_emotions::JOY[38], + b"\xEF\xBC\xBC(\xE2\x89\xA7\xE2\x96\xBD\xE2\x89\xA6)\xEF\xBC\x8F ", // (*°▽°*) - kaomoji_ru::positive_emotions::JOY[40], + b"(*\xC2\xB0\xE2\x96\xBD\xC2\xB0*) ", // (✧ω✧) - kaomoji_ru::positive_emotions::JOY[42], - // ヽ(*⌒▽⌒*)ノ - kaomoji_ru::positive_emotions::JOY[43], + b"(\xE2\x9C\xA7\xCF\x89\xE2\x9C\xA7) ", // ヽ(>∀<☆)ノ - kaomoji_ru::positive_emotions::JOY[48], + b"\xE3\x83\xBD(>\xE2\x88\x80<\xE2\x98\x86)\xE3\x83\x8E ", // o(≧▽≦)o - kaomoji_ru::positive_emotions::JOY[49], + b"o(\xE2\x89\xA7\xE2\x96\xBD\xE2\x89\xA6)o ", // (☆ω☆) - kaomoji_ru::positive_emotions::JOY[50], + b"(\xE2\x98\x86\xCF\x89\xE2\x98\x86) ", // (っ˘ω˘ς ) - kaomoji_ru::positive_emotions::JOY[51], + b"(\xE3\x81\xA3\xCB\x98\xCF\x89\xCB\x98\xCF\x82 ) ", // \(★ω★)/ - kaomoji_ru::positive_emotions::JOY[57], + b"\\(\xE2\x98\x85\xCF\x89\xE2\x98\x85)/ ", // (╯✧▽✧)╯ - kaomoji_ru::positive_emotions::JOY[60], + b"(\xE2\x95\xAF\xE2\x9C\xA7\xE2\x96\xBD\xE2\x9C\xA7)\xE2\x95\xAF ", // o(>ω<)o - kaomoji_ru::positive_emotions::JOY[61], - // (´・ᴗ・ ` ) - kaomoji_ru::positive_emotions::JOY[72], - // (¬‿¬ ) - kaomoji_ru::positive_emotions::JOY[77], - // („• ᴗ •„) - kaomoji_ru::positive_emotions::JOY[84], + b"o(>\xCF\x89<)o ", // (´ ω `♡) - kaomoji_ru::positive_emotions::LOVE[12], + b"(\xC2\xB4 \xCF\x89 `\xE2\x99\xA1) ", // (♡°▽°♡) - kaomoji_ru::positive_emotions::LOVE[17], + b"(\xE2\x99\xA1\xC2\xB0\xE2\x96\xBD\xC2\xB0\xE2\x99\xA1) ", // ♡(。- ω -) - kaomoji_ru::positive_emotions::LOVE[18], - // (´。• ω •。`) ♡ - kaomoji_ru::positive_emotions::LOVE[22], + b"\xE2\x99\xA1(\xEF\xBD\xA1- \xCF\x89 -) ", // (❤ω❤) - kaomoji_ru::positive_emotions::LOVE[39], - // (´,,•ω•,,)♡ - kaomoji_ru::positive_emotions::LOVE[45], + b"(\xE2\x9D\xA4\xCF\x89\xE2\x9D\xA4) ", // (*ノωノ) - kaomoji_ru::positive_emotions::EMBARRESMENT[5], - // (⁄ ⁄•⁄ω⁄•⁄ ⁄) - kaomoji_ru::positive_emotions::EMBARRESMENT[17], + b"(*\xEF\xBE\x89\xCF\x89\xEF\xBE\x89) ", // (# ̄ω ̄) - kaomoji_ru::negative_emotions::DISSATISFACTION[7], + b"(\xEF\xBC\x83\xEF\xBF\xA3\xCF\x89\xEF\xBF\xA3) ", // (>m<) - kaomoji_ru::negative_emotions::DISSATISFACTION[9], - // (」°ロ°)」 - kaomoji_ru::negative_emotions::DISSATISFACTION[10], + b"(\xEF\xBC\x9E\xEF\xBD\x8D\xEF\xBC\x9C) ", // (ᗒᗣᗕ)՞ - kaomoji_ru::negative_emotions::DISSATISFACTION[24], + b"(\xE1\x97\x92\xE1\x97\xA3\xE1\x97\x95)\xD5\x9E ", // (#`Д´) - kaomoji_ru::negative_emotions::ANGER[0], - // (・`ω´・) - kaomoji_ru::negative_emotions::ANGER[4], + b"(\xEF\xBC\x83`\xD0\x94\xC2\xB4) ", // (°ㅂ°╬) - kaomoji_ru::negative_emotions::ANGER[17], + b"(\xC2\xB0\xE3\x85\x82\xC2\xB0\xE2\x95\xAC) ", // (╬ Ò﹏Ó) - kaomoji_ru::negative_emotions::ANGER[25], + b"(\xE2\x95\xAC \xC3\x92\xEF\xB9\x8F\xC3\x93) ", // (´-ω-`) - kaomoji_ru::negative_emotions::SADNESS[2], + b"(\xC2\xB4-\xCF\x89-`) ", // (-ω-、) - kaomoji_ru::negative_emotions::SADNESS[6], - // ( ; ω ; ) - kaomoji_ru::negative_emotions::SADNESS[9], + b"(-\xCF\x89-\xE3\x80\x81) ", // ( ╥ω╥ ) - kaomoji_ru::negative_emotions::SADNESS[16], + b"( \xE2\x95\xA5\xCF\x89\xE2\x95\xA5 ) ", // (ノωヽ) - kaomoji_ru::negative_emotions::FEAR[0], + b"(\xE3\x83\x8E\xCF\x89\xE3\x83\xBD) ", // (・_・ヾ - kaomoji_ru::neutral_emotions::CONFUSSION[5], + b"(\xE3\x83\xBB_\xE3\x83\xBB\xE3\x83\xBE ", // ╮( ̄ω ̄;)╭ - kaomoji_ru::neutral_emotions::CONFUSSION[10], + b"\xE2\x95\xAE(\xEF\xBF\xA3\xCF\x89\xEF\xBF\xA3;)\xE2\x95\xAD ", // (*・ω・)ノ - kaomoji_ru::various_actions::GREETING[0], + b"(*\xE3\x83\xBB\xCF\x89\xE3\x83\xBB)\xEF\xBE\x89 ", // (✧∀✧)/ - kaomoji_ru::various_actions::GREETING[25], + b"(\xE2\x9C\xA7\xE2\x88\x80\xE2\x9C\xA7)/ ", // (つ≧▽≦)つ - kaomoji_ru::various_actions::HUGGING[1], + b"(\xE3\x81\xA4\xE2\x89\xA7\xE2\x96\xBD\xE2\x89\xA6)\xE3\x81\xA4 ", // (つ✧ω✧)つ - kaomoji_ru::various_actions::HUGGING[2], - // ⊂(´• ω •`⊂) - kaomoji_ru::various_actions::HUGGING[8], + b"(\xE3\x81\xA4\xE2\x9C\xA7\xCF\x89\xE2\x9C\xA7)\xE3\x81\xA4 ", // ⊂(・ω・*⊂) - kaomoji_ru::various_actions::HUGGING[9], + b"\xE2\x8A\x82(\xEF\xBD\xA5\xCF\x89\xEF\xBD\xA5*\xE2\x8A\x82) ", // (^ω~) - kaomoji_ru::various_actions::WINKING[3], + b"(^\xCF\x89~) ", // |・ω・) - kaomoji_ru::various_actions::HIDING[0], - // ☆ミ(o*・ω・)ノ - kaomoji_ru::various_actions::RUNNING[0], - // C= C= C= C= C=┌(;・ω・)┘ - kaomoji_ru::various_actions::RUNNING[1], - // ε===(っ≧ω≦)っ - kaomoji_ru::various_actions::RUNNING[6], - // (-ω-) zzZ - kaomoji_ru::various_actions::SLEEPING[3], + b"|\xEF\xBD\xA5\xCF\x89\xEF\xBD\xA5) ", // (=^・ω・^=) - kaomoji_ru::animals::CAT[0], + b"(=^\xEF\xBD\xA5\xCF\x89\xEF\xBD\xA5^=) ", // (=^・ェ・^=) - kaomoji_ru::animals::CAT[1], + b"(=^\xEF\xBD\xA5\xEF\xBD\xAA\xEF\xBD\xA5^=) ", // (=①ω①=) - kaomoji_ru::animals::CAT[2], + b"(=\xE2\x91\xA0\xCF\x89\xE2\x91\xA0=) ", // ( =ω=)..nyaa - kaomoji_ru::animals::CAT[3], - // (= ; ェ ; =) - kaomoji_ru::animals::CAT[4], + b"( =\xCF\x89=)..nyaa ", // (=`ω´=) - kaomoji_ru::animals::CAT[5], + b"(=`\xCF\x89\xC2\xB4=) ", // (=^‥^=) - kaomoji_ru::animals::CAT[6], + b"(=^\xE2\x80\xA5^=) ", // ( =ノωヽ=) - kaomoji_ru::animals::CAT[9], - // (=^ ◡ ^=) - kaomoji_ru::animals::CAT[11], + b"(=^ \xE2\x97\xA1 ^=) ", // (=^-ω-^=) - kaomoji_ru::animals::CAT[12], + b"(\xEF\xBC\xBE\xE2\x80\xA2 \xCF\x89 \xE2\x80\xA2\xEF\xBC\xBE) ", // ヾ(=`ω´=)ノ” - kaomoji_ru::animals::CAT[13], - // (^• ω •^) - kaomoji_ru::animals::CAT[14], + b"(/ =\xCF\x89=)/ ", // (/ =ω=)/ - kaomoji_ru::animals::CAT[15], + b"\xE0\xB8\x85(\xE2\x80\xA2 \xC9\xAA \xE2\x80\xA2)\xE0\xB8\x85 ", // ฅ(•ㅅ•❀)ฅ - kaomoji_ru::animals::CAT[16], - // ଲ(ⓛ ω ⓛ)ଲ - kaomoji_ru::animals::CAT[18], - // (^=◕ᴥ◕=^) - kaomoji_ru::animals::CAT[19], + b"\xE0\xAC\xB2(\xE2\x93\x9B \xCF\x89 \xE2\x93\x9B)\xE0\xAC\xB2 ", // ( =ω= ) - kaomoji_ru::animals::CAT[20], + b"(^=\xE2\x97\x95\xE1\xB4\xA5\xE2\x97\x95=^) ", // (^◔ᴥ◔^) - kaomoji_ru::animals::CAT[25], + b"\xE0\xB8\x95(=\xCF\x89=)\xE0\xB8\x95 ", // ( ・ω・)☞ - kaomoji_ru::special::POINTING, + b"(\xE3\x80\x80\xEF\xBD\xA5\xCF\x89\xEF\xBD\xA5)\xE2\x98\x9E ", ]; -pub const ASCII_SIZE: usize = ascii_len(&FACES); -pub const ASCII: [&[u8]; ASCII_SIZE] = ascii_array(&FACES); +pub const MIXED_FACES_SIZE: usize = mixed_len(&ASCII_FACES, &UNICODE_FACES); +pub const MIXED_FACES: [&[u8]; MIXED_FACES_SIZE] = mixed_array(&ASCII_FACES, &UNICODE_FACES); -pub const fn ascii_len(array: &[&[u8]]) -> usize { - let mut result = 0; - let len = array.len(); - let mut head = 0; - while head != len { - let mut ascii_head = 0; - let ascii_len = array[head].len(); - let mut ascii_res = 0; - while ascii_head != ascii_len { - if array[head][ascii_head].is_ascii() { - ascii_res += 1; - } - ascii_head += 1; - } - if ascii_res == array[head].len() { - result += 1; - } - head += 1; - } - result +pub const fn mixed_len(ascii_array: &[&[u8]], unicode_array: &[&[u8]]) -> usize { + unicode_array.len() + ascii_array.len() } -pub const fn ascii_array(array: &'static [&'static [u8]]) -> [&'static [u8]; ASCII_SIZE] { - let mut ascii_array: [&'static [u8]; ASCII_SIZE] = [&[]; ASCII_SIZE]; - let mut result_head = 0; - let len = array.len(); - let mut head = 0; - while head != len { - let mut ascii_head = 0; - let ascii_len = array[head].len(); - let mut ascii_res = 0; - while ascii_head != ascii_len { - if array[head][ascii_head].is_ascii() { - ascii_res += 1; - } - ascii_head += 1; - } - if ascii_res == array[head].len() { - ascii_array[result_head] = array[head]; - result_head += 1; - } - head += 1; +pub const fn mixed_array( + ascii_array: &'static [&'static [u8]], + unicode_array: &'static [&'static [u8]], +) -> [&'static [u8]; MIXED_FACES_SIZE] { + let mut mixed_array: [&'static [u8]; MIXED_FACES_SIZE] = [&[]; MIXED_FACES_SIZE]; + let ascii_len = ascii_array.len(); + let mut count = 0; + let mut second_count = 0; + + while count < ascii_len { + mixed_array[count] = ascii_array[count]; + count += 1; } - ascii_array + + while count < MIXED_FACES_SIZE { + mixed_array[count] = unicode_array[second_count]; + count += 1; + second_count += 1; + } + + mixed_array } pub const ACTIONS_SIZE: usize = 17; @@ -268,4 +220,4 @@ pub const ACTIONS: [&[u8]; ACTIONS_SIZE] = [ b"*pokes you* ", b"*teleports behind you* ", b"*shuffles closer* ", -]; +]; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 377a431..030f14b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(all(feature = "bench", test), feature(test))] use std::fs::File; -use std::io::{BufWriter, Error, ErrorKind, Write}; +use std::io::{BufWriter, Error, stdin, stdout, Write}; use std::path::Path; use std::str::from_utf8_unchecked; @@ -9,10 +9,10 @@ use ahash::RandomState; use linkify::{LinkFinder, LinkKind}; use memmap::Mmap; -use constants::ACTIONS_SIZE; -use constants::FACES; -use constants::FACES_SIZE; -use constants::{ACTIONS, ASCII, ASCII_SIZE}; +use constants::{ + ACTIONS, ACTIONS_SIZE, ASCII_FACES, ASCII_FACES_SIZE, MIXED_FACES, MIXED_FACES_SIZE, + UNICODE_FACES, UNICODE_FACES_SIZE, +}; mod constants; @@ -50,18 +50,25 @@ macro_rules! random_int { }; } +macro_rules! write { + ($out:expr, $bytes:expr) => { + $out.write_all($bytes) + }; +} + #[derive(Debug)] pub struct UwUify<'a> { text: &'a str, - input: &'a str, - output: &'a str, + infile: &'a str, + outfile: &'a str, + ascii_only: bool, + unicode_only: bool, + random: RandomState, words: f64, faces: f64, actions: f64, stutters: f64, - random: RandomState, - ascii: bool, - is_runtime: bool, + supplied_at_runtime: bool, linkify: LinkFinder, } @@ -69,15 +76,16 @@ impl<'a> Default for UwUify<'a> { fn default() -> Self { Self { text: "", - input: "", - output: "", + infile: "", + outfile: "", + ascii_only: false, + unicode_only: false, + random: RandomState::with_seeds(69, 420, 96, 84), words: 1.0, faces: 0.05, actions: 0.125, stutters: 0.225, - random: RandomState::with_seeds(69, 420, 96, 84), - is_runtime: false, - ascii: false, + supplied_at_runtime: false, linkify: LinkFinder::new(), } } @@ -88,13 +96,14 @@ impl<'a> UwUify<'a> { text: Option<&'a str>, infile: Option<&'a str>, outfile: Option<&'a str>, + ascii_only: bool, + unicode_only: bool, + random: bool, words: Option<&'a str>, faces: Option<&'a str>, actions: Option<&'a str>, stutters: Option<&'a str>, - ascii: bool, - random: bool, - is_runtime: bool, + supplied_at_runtime: bool, ) -> UwUify<'a> { let mut linkify = LinkFinder::new(); linkify.kinds(&[LinkKind::Email, LinkKind::Url]); @@ -102,10 +111,11 @@ impl<'a> UwUify<'a> { let mut uwuify = UwUify { text: text.unwrap_or_default(), - input: infile.unwrap_or_default(), - output: outfile.unwrap_or_default(), - ascii, - is_runtime, + infile: infile.unwrap_or_default(), + outfile: outfile.unwrap_or_default(), + ascii_only, + unicode_only, + supplied_at_runtime, linkify, ..Default::default() }; @@ -134,16 +144,25 @@ impl<'a> UwUify<'a> { // Handle Text if !self.text.is_empty() { // Handle Text Output - if !self.output.is_empty() { - if Path::new(&self.output).exists() { - return Err(Error::new( - ErrorKind::AlreadyExists, - format!("File '{}' already exists, aborting operation", &self.output), - )); + if !self.outfile.is_empty() { + if Path::new(&self.outfile).exists() { + let mut overwrite_file = String::new(); + print!( + "File '{}' already exists, would you like to overwrite this file? [Y/n] ", + self.outfile + ); + + stdout().flush()?; + stdin().read_line(&mut overwrite_file)?; + + if overwrite_file.to_lowercase().trim() != "y" { + println!("Exiting..."); + return Ok(()); + } } let uwu_progress_bar = progress_bar!(); - self.uwuify_sentence(self.text, &mut BufWriter::new(File::create(&self.output)?))?; + self.uwuify_sentence(self.text, &mut BufWriter::new(File::create(&self.outfile)?))?; uwu_progress_bar.finish_with_message("UwU'ifying Complete!"); } else { #[cfg(not(test))] @@ -153,17 +172,26 @@ impl<'a> UwUify<'a> { } } else { // Handle File I/O - if Path::new(&self.output).exists() { - return Err(Error::new( - ErrorKind::AlreadyExists, - format!("File '{}' already exists, aborting operation", &self.output), - )); + if Path::new(&self.outfile).exists() { + let mut overwrite_file = String::new(); + print!( + "File '{}' already exists, would you like to overwrite this file? [Y/n] ", + self.outfile + ); + + stdout().flush()?; + stdin().read_line(&mut overwrite_file)?; + + if overwrite_file.to_lowercase().trim() != "y" { + println!("Exiting..."); + return Ok(()); + } } let uwu_progress_bar = progress_bar!(); self.uwuify_sentence( - unsafe { from_utf8_unchecked(Mmap::map(&File::open(&self.input)?)?.as_ref()) }, - &mut BufWriter::new(File::create(&self.output)?), + unsafe { from_utf8_unchecked(Mmap::map(&File::open(&self.infile)?)?.as_ref()) }, + &mut BufWriter::new(File::create(&self.outfile)?), )?; uwu_progress_bar.finish_with_message("UwU'ifying Complete!"); } @@ -179,43 +207,63 @@ impl<'a> UwUify<'a> { let mut seeder = new_seeder!(word, &self.random); let random_value = random_float!(&mut seeder); - if !self.is_runtime { + if !self.supplied_at_runtime { if random_value <= self.faces { - if self.ascii { - out.write_all(ASCII[random_int!(&mut seeder, 0..ASCII_SIZE)])?; + if self.ascii_only { + write!( + out, + ASCII_FACES[random_int!(&mut seeder, 0..ASCII_FACES_SIZE)] + )?; + } else if self.unicode_only { + write!( + out, + UNICODE_FACES[random_int!(&mut seeder, 0..UNICODE_FACES_SIZE)] + )?; } else { - out.write_all(FACES[random_int!(&mut seeder, 0..FACES_SIZE)])?; + write!( + out, + MIXED_FACES[random_int!(&mut seeder, 0..MIXED_FACES_SIZE)] + )?; } - out.write_all(b" ")?; } else if random_value <= self.actions { - out.write_all(ACTIONS[random_int!(&mut seeder, 0..ACTIONS_SIZE)])?; + write!(out, ACTIONS[random_int!(&mut seeder, 0..ACTIONS_SIZE)])?; } else if random_value <= self.stutters { match word[0] { - b'L' | b'R' => out.write_all(b"W"), - b'l' | b'r' => out.write_all(b"w"), - byte => out.write_all(&[byte]), + b'L' | b'R' => write!(out, b"W"), + b'l' | b'r' => write!(out, b"w"), + byte => write!(out, &[byte]), }?; - out.write_all(b"-")?; + write!(out, b"-")?; } } else { if random_value <= self.faces { - if self.ascii { - out.write_all(ASCII[random_int!(&mut seeder, 0..ASCII_SIZE)])?; + if self.ascii_only { + write!( + out, + ASCII_FACES[random_int!(&mut seeder, 0..ASCII_FACES_SIZE)] + )?; + } else if self.unicode_only { + write!( + out, + UNICODE_FACES[random_int!(&mut seeder, 0..UNICODE_FACES_SIZE)] + )?; } else { - out.write_all(FACES[random_int!(&mut seeder, 0..FACES_SIZE)])?; + write!( + out, + MIXED_FACES[random_int!(&mut seeder, 0..MIXED_FACES_SIZE)] + )?; } - out.write_all(b" ")?; } if random_value <= self.actions { - out.write_all(ACTIONS[random_int!(&mut seeder, 0..ACTIONS_SIZE)])?; + write!(out, ACTIONS[random_int!(&mut seeder, 0..ACTIONS_SIZE)])?; } if random_value <= self.stutters { match word[0] { - b'L' | b'R' => out.write_all(b"W"), - b'l' | b'r' => out.write_all(b"w"), - byte => out.write_all(&[byte]), + b'L' | b'R' => write!(out, b"W"), + b'l' | b'r' => write!(out, b"w"), + byte => write!(out, &[byte]), }?; - out.write_all(b"-")?; + write!(out, b"-")?; } } @@ -226,26 +274,27 @@ impl<'a> UwUify<'a> { > 0 || random_value > self.words { - out.write_all(word)?; + write!(out, word)?; } else { (0..word.len()).try_for_each(|index| match word[index] { - b'L' | b'R' => out.write_all(b"W"), - b'l' | b'r' => out.write_all(b"w"), + b'L' | b'R' => write!(out, b"W"), + b'l' | b'r' => write!(out, b"w"), b'A' | b'E' | b'I' | b'O' | b'U' | b'a' | b'e' | b'i' | b'o' | b'u' => { match word.get(index - 1).unwrap_or(&word[0]) { - b'N' | b'n' => out.write_all(&[b'y', word[index]]), - _ => out.write_all(&[word[index]]), + b'N' | b'n' => write!(out, &[b'y', word[index]]), + _ => write!(out, &[word[index]]), } } - byte => out.write_all(&[byte]), + byte => write!(out, &[byte]), })?; } - out.write_all(b" ") + write!(out, b" ") })?; - out.write_all(b"\n") + write!(out, b"\n") }) } } + #[cfg(test)] mod tests { #[cfg(feature = "bench")] @@ -258,14 +307,15 @@ mod tests { Some(include_str!("test.txt")), None, None, + false, + true, + false, None, None, None, None, false, - false, - false, ); b.iter(|| uwuify.uwuify()); } -} +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 04e95dc..9dd46f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,19 +18,13 @@ macro_rules! app { ) .arg( Arg::new("text") - .help("Text to uwu'ify") + .help("The text to uwu'ify") .short('t') .long("text") .value_name("TEXT") .required_unless_present_all(["infile", "outfile"]) .display_order(1), ) - .arg( - Arg::new("ascii-only") - .help("The output file will not use UTF-8 charecters") - .long("ascii-only") - .display_order(2), - ) .arg( Arg::new("infile") .help("The file to uwu'ify") @@ -40,7 +34,7 @@ macro_rules! app { .requires("outfile") .value_name("FILE") .value_hint(clap::ValueHint::FilePath) - .display_order(3), + .display_order(2), ) .arg( Arg::new("outfile") @@ -49,8 +43,28 @@ macro_rules! app { .long("outfile") .value_name("FILE") .value_hint(clap::ValueHint::FilePath) + .display_order(3), + ) + .arg( + Arg::new("ascii-only") + .help("The uwu'ified text will only include ASCII faces") + .long("ascii-only") + .conflicts_with("unicode-only") .display_order(4), ) + .arg( + Arg::new("unicode-only") + .help("The uwu'ified text will only include UTF-8 faces") + .long("unicode-only") + .display_order(5), + ) + .arg( + Arg::new("random") + .help("The flag to enable randomized uwu'ified text") + .short('r') + .long("random") + .display_order(6), + ) .arg( Arg::new("words") .help("The modifier to determine how many words to be uwu'ified") @@ -59,7 +73,7 @@ macro_rules! app { .value_name("VALUE") .default_value("1") .validator(is_between_zero_and_one) - .display_order(5), + .display_order(7), ) .arg( Arg::new("faces") @@ -69,7 +83,7 @@ macro_rules! app { .value_name("VALUE") .default_value("0.05") .validator(is_between_zero_and_one) - .display_order(6), + .display_order(8), ) .arg( Arg::new("actions") @@ -79,7 +93,7 @@ macro_rules! app { .value_name("VALUE") .default_value("0.125") .validator(is_between_zero_and_one) - .display_order(7), + .display_order(9), ) .arg( Arg::new("stutters") @@ -89,14 +103,7 @@ macro_rules! app { .value_name("VALUE") .default_value("0.225") .validator(is_between_zero_and_one) - .display_order(8), - ) - .arg( - Arg::new("random") - .help("Flag to enable/disable random uwu'ifying") - .short('r') - .long("random") - .display_order(9), + .display_order(10), ) }; } @@ -121,12 +128,13 @@ fn main() { matches.value_of("text"), matches.value_of("infile"), matches.value_of("outfile"), + matches.is_present("ascii-only"), + matches.is_present("unicode-only"), + matches.is_present("random"), matches.value_of("words"), matches.value_of("faces"), matches.value_of("actions"), matches.value_of("stutters"), - matches.is_present("ascii-only"), - matches.is_present("random"), is_runtime!( matches.occurrences_of("faces"), matches.occurrences_of("actions"), @@ -149,4 +157,4 @@ fn is_between_zero_and_one(input: &str) -> Result<(), &'static str> { return Ok(()); } Err("The value must be between 0.0 and 1.0") -} +} \ No newline at end of file