use std::io::Result;
use std::path;
use std::sync::mpsc;
use super::counter::Counter;
use super::threads::{handle, handle_in_thread};
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct App {
njobs: usize,
words: bool,
}
impl Default for App {
fn default() -> Self {
Self {
njobs: 1,
words: false,
}
}
}
impl App {
pub fn new(njobs: usize, words: bool) -> Self {
Self { njobs, words }
}
pub fn count(&self, path: &str) -> Result<usize> {
let target = path::PathBuf::from(path);
let mut counter = Counter::new(target);
let nfiles = counter.count_files()?;
let njobs: usize;
if self.njobs == 1 {
return Ok(self.adjust(handle(counter.files, self.words), nfiles));
} else {
njobs = self.njobs - 1;
}
let mut total = 0;
let mut position = 0;
let workloads = counter.generate_workloads(njobs, nfiles)?;
let files = counter.files;
let (tx, rx) = mpsc::channel();
for load in workloads {
let start = position;
let end = position + load;
position = end;
handle_in_thread(tx.clone(), files[start..end].to_vec(), self.words);
}
drop(tx);
for rcvd in rx {
total += rcvd;
}
Ok(self.adjust(total, nfiles))
}
fn adjust(&self, total: usize, nfiles: usize) -> usize {
if !self.words {
return total + nfiles;
}
total
}
pub fn set_njobs(&mut self, njobs: usize) -> usize {
self.njobs = njobs;
njobs
}
pub fn get_njobs(&self) -> usize {
self.njobs
}
pub fn get_words(&self) -> bool {
self.words
}
pub fn set_words(&mut self, value: bool) -> bool {
self.words = value;
value
}
}
#[cfg(test)]
mod app_tests {
use super::App;
#[test]
fn app_adjust_default() {
let app = App::default();
assert_eq!(app.adjust(10, 20), 30);
}
#[test]
fn app_adjust_new() {
let app = App::new(1, true);
assert_eq!(app.adjust(10, 20), 10);
}
}