|
|
|
@ -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) => {
|
|
|
|
|
<rand_xoshiro::Xoshiro256Plus as rand::SeedableRng>::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<T: Write>(&self, text: &str, out: &mut T) -> Result<(), Error> {
|
|
|
|
|
pub fn uwuify_sentence<T: Write>(&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,
|
|
|
|
|