izzilis/src/bot.rs

124 lines
3.7 KiB
Rust

use rand::Rng;
use std::{error::Error, io};
use crate::{
generator, model, publish,
selection::{self, Selector},
};
pub struct IzzilisBot<T: model::SampleModel, U: publish::Publisher, V: selection::Selector> {
generator: generator::Generator<T>,
publisher: U, // One day I'll figure out how to make this a vector with differing Publisher types
selector: V,
loaded_samples: Vec<String>,
}
impl<T, U, V> IzzilisBot<T, U, V>
where
T: model::SampleModel,
U: publish::Publisher,
V: selection::Selector,
{
pub fn new(
generator: generator::Generator<T>,
publisher: U,
selector: V,
) -> IzzilisBot<T, U, V> {
Self {
generator,
publisher,
loaded_samples: Vec::new(),
selector: selector,
}
}
pub fn generate_samples(&mut self) -> Option<io::Error> {
let lines_result = self.generator.generate_sample_lines();
let lines = match lines_result {
Ok(res) => res,
Err(err) => return Some(err),
};
for line in lines {
match self.selector.send_for_review(line) {
Some(err) => panic!("Failed selector read, yes shit error I know, help me"), // Yes, I know this is *abysmal* but idk how to deal with errors
// yet, so for the time being I have to suffer through this bad shit. Please help me, looking at this is suffering. I want it to end.
None => (),
}
}
self.loaded_samples = self.selector.collect_selected_samples(); // wtf happens to the original self.loaded_samples???????
None
}
pub fn publish(&mut self) -> Option<Box<dyn Error>> {
if self.loaded_samples.len() == 0 {
// Refresh samples. Either none have been generated so far,
// or generated ones are stale.
//
// This is a shit solution, but I'm going with it for v1
// purely because I don't know the language well enough to be
// confident in doing this via threads. Yet.
self.generate_samples();
}
let sample_index = rand::thread_rng().gen_range(0..self.loaded_samples.len() - 1);
let content = self.loaded_samples[sample_index].clone();
self.loaded_samples.remove(sample_index);
match self.publisher.publish(content) {
Some(err) => Some(err),
None => None,
}
}
}
#[cfg(tests)]
mod tests {
use std::io::{self, ErrorKind};
use crate::{generator, model, publish};
struct fake_sampler {
should_ok: bool,
ok_str: String,
}
struct fake_publisher {
should_ok: bool,
}
impl model::SampleModel for fake_sampler {
fn get_sample(&self) -> Result<String, io::Error> {
if self.should_ok {
return Ok(self.ok_str.clone());
}
Err(io::Error::new(ErrorKind::NotFound, "error"))
}
}
impl publish::Publisher for fake_publisher {
fn publish(&self, content: String) -> Option<Box<dyn std::error::Error>> {
if self.should_ok {
return None;
}
Some(Box::new(io::Error::new(ErrorKind::NotFound, "error")))
}
}
#[test]
fn generate_samples_populates() {
let model_ok_string = String::from("model_ok");
let model = fake_sampler {
should_ok: true,
ok_str: model_ok_string,
};
let gen = generator::Generator::new(model);
let publish = fake_publisher { should_ok: true };
let mut bot = super::IzzilisBot::new(gen, publish);
match bot.publish() {
Some(_) => panic!("publish failed"),
None => (),
}
}
}