Refactor & restore original seeding/modifier functionality

pull/4/head
sgoudham 3 years ago
parent 4fe9803068
commit 6a01ee9233

@ -1,17 +1,20 @@
use indicatif::{ProgressBar, ProgressStyle};
use linkify::{LinkFinder, LinkKind};
use rand::{Rng, RngCore, SeedableRng};
use rand_xoshiro::{Xoshiro256Plus, Xoshiro256PlusPlus};
use std::fs::File; use std::fs::File;
use std::io::{BufWriter, Error, Write}; use std::io::{stdout, BufWriter, Error, ErrorKind, Write};
use std::path::Path; use std::path::Path;
use std::str::from_utf8_unchecked;
use indicatif::{ProgressBar, ProgressStyle};
use linkify::{LinkFinder, LinkKind};
use memmap::Mmap;
use constants::ACTIONS; use constants::ACTIONS;
use constants::ACTIONS_SIZE; use constants::ACTIONS_SIZE;
use constants::FACES; use constants::FACES;
use constants::FACES_SIZE; use constants::FACES_SIZE;
use seeder::UwUSeeder;
mod constants; mod constants;
mod seeder;
macro_rules! progress_bar { macro_rules! progress_bar {
() => {{ () => {{
@ -34,8 +37,8 @@ pub struct UwUify<'a> {
faces: f64, faces: f64,
actions: f64, actions: f64,
stutters: f64, stutters: f64,
floating_rng: Xoshiro256Plus, random: bool,
int_rng: Xoshiro256PlusPlus, is_runtime: bool,
linkify: LinkFinder, linkify: LinkFinder,
} }
@ -49,8 +52,8 @@ impl<'a> Default for UwUify<'a> {
faces: 0.05, faces: 0.05,
actions: 0.125, actions: 0.125,
stutters: 0.225, stutters: 0.225,
floating_rng: Xoshiro256Plus::seed_from_u64(69), random: false,
int_rng: Xoshiro256PlusPlus::seed_from_u64(420), is_runtime: false,
linkify: LinkFinder::new(), linkify: LinkFinder::new(),
} }
} }
@ -66,25 +69,22 @@ impl<'a> UwUify<'a> {
actions: Option<&'a str>, actions: Option<&'a str>,
stutters: Option<&'a str>, stutters: Option<&'a str>,
random: bool, random: bool,
is_runtime: bool,
) -> UwUify<'a> { ) -> UwUify<'a> {
// I dislike this
let mut linkify = LinkFinder::new(); let mut linkify = LinkFinder::new();
linkify.kinds(&[LinkKind::Email, LinkKind::Url]); linkify.kinds(&[LinkKind::Email, LinkKind::Url]);
linkify.url_must_have_scheme(false); linkify.url_must_have_scheme(false);
let mut uwuify = UwUify { let mut uwuify = UwUify {
text: text.unwrap_or_default(), text: text.unwrap_or_default(),
input: infile.unwrap_or_default(), input: infile.unwrap_or_default(),
output: outfile.unwrap_or_default(), output: outfile.unwrap_or_default(),
random,
is_runtime,
linkify, linkify,
..Default::default() ..Default::default()
}; };
if random {
uwuify.floating_rng = Xoshiro256Plus::seed_from_u64(rand::rngs::OsRng.next_u64());
uwuify.int_rng = Xoshiro256PlusPlus::seed_from_u64(rand::rngs::OsRng.next_u64());
}
if let Some(words) = words { if let Some(words) = words {
uwuify.words = words.parse::<f64>().unwrap(); uwuify.words = words.parse::<f64>().unwrap();
} }
@ -97,6 +97,7 @@ impl<'a> UwUify<'a> {
if let Some(stutters) = stutters { if let Some(stutters) = stutters {
uwuify.stutters = stutters.parse::<f64>().unwrap(); uwuify.stutters = stutters.parse::<f64>().unwrap();
} }
uwuify uwuify
} }
@ -107,85 +108,78 @@ impl<'a> UwUify<'a> {
if !self.output.is_empty() { if !self.output.is_empty() {
if Path::new(&self.output).exists() { if Path::new(&self.output).exists() {
return Err(Error::new( return Err(Error::new(
std::io::ErrorKind::AlreadyExists, ErrorKind::AlreadyExists,
format!("File '{}' already exists, aborting operation", &self.output), format!("File '{}' already exists, aborting operation", &self.output),
)); ));
} }
let mut uwu_out_file = BufWriter::new(File::create(&self.output)?);
let uwu_progress_bar = progress_bar!(); let uwu_progress_bar = progress_bar!();
self.uwuify_sentence(self.text, &mut uwu_out_file)?; self.uwuify_sentence(self.text, &mut BufWriter::new(File::create(&self.output)?))?;
uwu_progress_bar.finish_with_message("UwU'ifying Complete!"); uwu_progress_bar.finish_with_message("UwU'ifying Complete!");
Ok(())
} else { } else {
#[cfg(not(test))] self.uwuify_sentence(self.text, &mut BufWriter::new(stdout().lock()))?;
let stdout = std::io::stdout();
#[cfg(not(test))]
let mut out = BufWriter::new(stdout.lock());
#[cfg(test)]
let mut out = std::io::sink();
self.uwuify_sentence(self.text, &mut out)?;
#[cfg(not(test))]
out.write_all(b"\n")?;
Ok(())
} }
} else { } else {
// Handle File I/O // Handle File I/O
if Path::new(&self.output).exists() { if Path::new(&self.output).exists() {
return Err(Error::new( return Err(Error::new(
std::io::ErrorKind::AlreadyExists, ErrorKind::AlreadyExists,
format!("File '{}' already exists, aborting operation", &self.output), format!("File '{}' already exists, aborting operation", &self.output),
)); ));
} }
let uwu_progress_bar = progress_bar!(); let uwu_progress_bar = progress_bar!();
self.uwuify_sentence( self.uwuify_sentence(
unsafe { unsafe { from_utf8_unchecked(Mmap::map(&File::open(&self.input)?)?.as_ref()) },
std::str::from_utf8_unchecked(
memmap::Mmap::map(&File::open(&self.input)?)?.as_ref(),
)
},
&mut BufWriter::new(File::create(&self.output)?), &mut BufWriter::new(File::create(&self.output)?),
)?; )?;
uwu_progress_bar.finish_with_message("UwU'ifying Complete!"); uwu_progress_bar.finish_with_message("UwU'ifying Complete!");
Ok(())
} }
Ok(())
} }
pub fn uwuify_sentence<T: Write>( pub fn uwuify_sentence<T: Write>(&mut self, text: &str, out: &mut T) -> Result<(), Error> {
&mut self,
text: &str,
out: &mut T,
) -> Result<(), std::io::Error> {
text.lines().try_for_each(|line| { text.lines().try_for_each(|line| {
line.split_whitespace() line.split_whitespace()
.map(|f| f.as_bytes()) .map(|word_str| word_str.as_bytes())
.try_for_each(|word| { .try_for_each(|word| {
let random_value = self.floating_rng.gen_range(0.0..1.0); let mut seeder = UwUSeeder::new(word, self.random);
let random_value = seeder.random_float();
if random_value <= self.faces {
out.write_all(FACES[self.int_rng.gen_range(0..FACES_SIZE)])?; if !self.is_runtime {
out.write_all(b" ")?; if random_value <= self.faces {
} else if random_value <= self.actions { out.write_all(FACES[seeder.random_int(0..FACES_SIZE)])?;
out.write_all(ACTIONS[self.int_rng.gen_range(0..ACTIONS_SIZE)])?; } else if random_value <= self.actions {
out.write_all(b" ")?; out.write_all(ACTIONS[seeder.random_int(0..ACTIONS_SIZE)])?;
} else if random_value <= self.stutters { } else if random_value <= self.stutters {
(0..self.int_rng.gen_range(1..2)) match word[0] {
.into_iter() b'L' | b'R' => out.write_all(b"W"),
.try_for_each(|_| { b'l' | b'r' => out.write_all(b"w"),
match word[0] { byte => out.write_all(&[byte]),
b'L' | b'R' => out.write_all(b"W"), }?;
b'l' | b'r' => out.write_all(b"w"), out.write_all(b"-")?;
b => out.write_all(&[b]), }
}?; } else {
out.write_all(b"-") if random_value <= self.faces {
})?; out.write_all(FACES[seeder.random_int(0..FACES_SIZE)])?;
}
if random_value <= self.actions {
out.write_all(ACTIONS[seeder.random_int(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]),
}?;
out.write_all(b"-")?;
}
} }
if self if self
.linkify .linkify
.links(unsafe { std::str::from_utf8_unchecked(word) }) .links(unsafe { from_utf8_unchecked(word) })
.count() .count()
> 0 > 0
|| random_value > self.words || random_value > self.words
@ -195,13 +189,13 @@ impl<'a> UwUify<'a> {
(0..word.len()).try_for_each(|index| match word[index] { (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' => out.write_all(b"w"), b'l' | b'r' => out.write_all(b"w"),
b'E' | b'e' | b'A' | b'I' | b'O' | b'U' | b'a' | b'i' | b'o' | b'u' => { 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]) { match word.get(index - 1).unwrap_or(&word[0]) {
b'N' | b'n' => out.write_all(&[b'y', word[index]]), b'N' | b'n' => out.write_all(&[b'y', word[index]]),
_ => out.write_all(&[word[index]]), _ => out.write_all(&[word[index]]),
} }
} }
b => out.write_all(&[b]), byte => out.write_all(&[byte]),
})?; })?;
} }
out.write_all(b" ") out.write_all(b" ")
@ -209,4 +203,4 @@ impl<'a> UwUify<'a> {
out.write_all(b"\n") out.write_all(b"\n")
}) })
} }
} }
Loading…
Cancel
Save