use rand::Rng; use std::{error::Error, io}; use crate::{generator, model, publish}; pub struct IzzilisBot { generator: generator::Generator, publisher: U, // One day I'll figure out how to make this a vector with differing Publisher types loaded_samples: Vec, } impl IzzilisBot where T: model::SampleModel, U: publish::Publisher, { pub fn new(generator: generator::Generator, publisher: U) -> IzzilisBot { Self { generator, publisher, loaded_samples: Vec::new(), } } fn generate_samples(&mut self) -> Option { let lines_result = self.generator.generate_sample_lines(); let lines = match lines_result { Ok(res) => res, Err(err) => return Some(err), }; self.loaded_samples = lines; // wtf happens to the original self.loaded_samples??????? None } pub fn publish(&mut self) -> Option> { if self.loaded_samples.len() < 5 { // 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 { 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> { 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 => (), } } }