From b6dcad187805c66add285785738d07d20067bab6 Mon Sep 17 00:00:00 2001 From: Isaac Mills Date: Tue, 1 Feb 2022 19:10:20 -0500 Subject: [PATCH] Add ascii only option --- src/constants.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 44 +++++++++++++++++++++--------------------- src/main.rs | 26 ++++++++++++++++--------- 3 files changed, 88 insertions(+), 32 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 4102fa9..afa81fc 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,5 +1,4 @@ pub const FACES_SIZE: usize = 106; - pub const FACES: [&[u8]; FACES_SIZE] = [ b"OwO", b"UwU", @@ -201,6 +200,55 @@ pub const FACES: [&[u8]; FACES_SIZE] = [ kaomoji_ru::special::POINTING, ]; +pub const ASCII_SIZE: usize = ascii_len(&FACES); +pub const ASCII: [&[u8]; ASCII_SIZE] = ascii_array(&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 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; + } + ascii_array +} + pub const ACTIONS_SIZE: usize = 17; pub const ACTIONS: [&[u8]; ACTIONS_SIZE] = [ b"*notices bulge* ", diff --git a/src/lib.rs b/src/lib.rs index 1f73cf0..722b609 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,14 +5,15 @@ use std::io::{BufWriter, Error, ErrorKind, Write}; use std::path::Path; use std::str::from_utf8_unchecked; -use ahash::RandomState; use linkify::{LinkFinder, LinkKind}; use memmap::Mmap; -use constants::ACTIONS; use constants::ACTIONS_SIZE; use constants::FACES; use constants::FACES_SIZE; +use constants::{ACTIONS, ASCII, ASCII_SIZE}; +use rand::SeedableRng; +use rand_xoshiro::Xoshiro256Plus; mod constants; @@ -30,14 +31,6 @@ macro_rules! progress_bar { }}; } -macro_rules! new_seeder { - ($word:expr, $random:expr) => { - ::seed_from_u64( - <[u8] as ahash::CallHasher>::get_hash($word, $random), - ) - }; -} - macro_rules! random_float { ($seeder:expr) => { rand::Rng::gen_range($seeder, 0.0..1.0) @@ -59,7 +52,8 @@ pub struct UwUify<'a> { faces: f64, actions: f64, stutters: f64, - random: RandomState, + random: Xoshiro256Plus, + ascii: bool, is_runtime: bool, linkify: LinkFinder, } @@ -74,8 +68,9 @@ impl<'a> Default for UwUify<'a> { faces: 0.05, actions: 0.125, stutters: 0.225, - random: RandomState::with_seeds(69, 420, 28, 95), + random: Xoshiro256Plus::seed_from_u64(69420), is_runtime: false, + ascii: false, linkify: LinkFinder::new(), } } @@ -90,6 +85,7 @@ impl<'a> UwUify<'a> { faces: Option<&'a str>, actions: Option<&'a str>, stutters: Option<&'a str>, + ascii: bool, random: bool, is_runtime: bool, ) -> UwUify<'a> { @@ -101,13 +97,14 @@ impl<'a> UwUify<'a> { text: text.unwrap_or_default(), input: infile.unwrap_or_default(), output: outfile.unwrap_or_default(), + ascii, is_runtime, linkify, ..Default::default() }; if random { - uwuify.random = RandomState::new(); + uwuify.random = Xoshiro256Plus::from_entropy(); } if let Some(words) = words { @@ -126,7 +123,7 @@ impl<'a> UwUify<'a> { uwuify } - pub fn uwuify(&self) -> Result<(), Error> { + pub fn uwuify(&mut self) -> Result<(), Error> { // Handle Text if !self.text.is_empty() { // Handle Text Output @@ -167,20 +164,19 @@ impl<'a> UwUify<'a> { Ok(()) } - pub fn uwuify_sentence(&self, text: &str, out: &mut T) -> Result<(), Error> { + pub fn uwuify_sentence(&mut self, text: &str, out: &mut T) -> Result<(), Error> { text.lines().try_for_each(|line| { line.split_whitespace() .map(|word_str| word_str.as_bytes()) .try_for_each(|word| { - let mut seeder = new_seeder!(word, &self.random); - let random_value = random_float!(&mut seeder); + let random_value = random_float!(&mut self.random); if !self.is_runtime { if random_value <= self.faces { - out.write_all(FACES[random_int!(&mut seeder, 0..FACES_SIZE)])?; + out.write_all(FACES[random_int!(&mut self.random, 0..FACES_SIZE)])?; out.write_all(b" ")?; } else if random_value <= self.actions { - out.write_all(ACTIONS[random_int!(&mut seeder, 0..ACTIONS_SIZE)])?; + out.write_all(ACTIONS[random_int!(&mut self.random, 0..ACTIONS_SIZE)])?; } else if random_value <= self.stutters { match word[0] { b'L' | b'R' => out.write_all(b"W"), @@ -191,11 +187,15 @@ impl<'a> UwUify<'a> { } } else { if random_value <= self.faces { - out.write_all(FACES[random_int!(&mut seeder, 0..FACES_SIZE)])?; + if self.ascii { + out.write_all(ASCII[random_int!(&mut self.random, 0..ASCII_SIZE)])?; + } else { + out.write_all(FACES[random_int!(&mut self.random, 0..FACES_SIZE)])?; + } out.write_all(b" ")?; } if random_value <= self.actions { - out.write_all(ACTIONS[random_int!(&mut seeder, 0..ACTIONS_SIZE)])?; + out.write_all(ACTIONS[random_int!(&mut self.random, 0..ACTIONS_SIZE)])?; } if random_value <= self.stutters { match word[0] { @@ -242,7 +242,7 @@ mod tests { #[cfg(feature = "bench")] #[bench] fn uwu_bench(b: &mut test::Bencher) { - let uwuify = super::UwUify::new( + let mut uwuify = super::UwUify::new( Some(include_str!("test.txt")), None, None, diff --git a/src/main.rs b/src/main.rs index 29bd31c..0e1296b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,12 @@ macro_rules! app { .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") @@ -34,7 +40,7 @@ macro_rules! app { .requires("outfile") .value_name("FILE") .value_hint(clap::ValueHint::FilePath) - .display_order(2), + .display_order(3), ) .arg( Arg::new("outfile") @@ -43,7 +49,7 @@ macro_rules! app { .long("outfile") .value_name("FILE") .value_hint(clap::ValueHint::FilePath) - .display_order(3), + .display_order(4), ) .arg( Arg::new("words") @@ -53,7 +59,7 @@ macro_rules! app { .value_name("VALUE") .default_value("1") .validator(is_between_zero_and_one) - .display_order(4), + .display_order(5), ) .arg( Arg::new("faces") @@ -63,7 +69,7 @@ macro_rules! app { .value_name("VALUE") .default_value("0.05") .validator(is_between_zero_and_one) - .display_order(5), + .display_order(6), ) .arg( Arg::new("actions") @@ -73,7 +79,7 @@ macro_rules! app { .value_name("VALUE") .default_value("0.125") .validator(is_between_zero_and_one) - .display_order(6), + .display_order(7), ) .arg( Arg::new("stutters") @@ -83,14 +89,14 @@ macro_rules! app { .value_name("VALUE") .default_value("0.225") .validator(is_between_zero_and_one) - .display_order(7), + .display_order(8), ) .arg( Arg::new("random") .help("Flag to enable/disable random uwu'ifying") .short('r') .long("random") - .display_order(8), + .display_order(9), ) }; } @@ -102,8 +108,8 @@ macro_rules! clap_panic { } macro_rules! is_runtime { - ($faces:expr, $actions:expr, $stutters:expr) => { - $faces > 0 || $actions > 0 || $stutters > 0 + ($faces:expr, $actions:expr, $ascii:expr, $stutters:expr) => { + $faces > 0 || $actions > 0 || $ascii > 0 || $stutters > 0 }; } @@ -119,10 +125,12 @@ fn main() { 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"), + matches.occurrences_of("ascii-only"), matches.occurrences_of("stutters") ), )