extern crate permutate;
mod arguments;
mod buffer;
mod man;
use std::io::{self, StdoutLock, Write};
use std::process::exit;
use arguments::InputError;
use buffer::StdoutBuffer;
use buffer::platform::BUFFER_SIZE;
use permutate::Permutator;
fn main() {
let stdout = io::stdout();
let stderr = io::stderr();
let mut stdout = stdout.lock();
let mut stderr = stderr.lock();
let (input, benchmark, interpret_files, no_delimiters) =
arguments::parse_options(&mut stdout);
let mut list_vector = Vec::new();
match arguments::parse_arguments(&mut list_vector, &input.join(" "), interpret_files) {
Ok(_) => {
let tmp: Vec<Vec<&str>> = list_vector.iter()
.map(|list| list.iter().map(AsRef::as_ref).collect::<Vec<&str>>())
.collect();
let list_array: Vec<&[&str]> = tmp.iter().map(AsRef::as_ref).collect();
let mut permutator = Permutator::new(&list_array[..]);
if benchmark {
let _ = permutator.count();
} else {
if no_delimiters {
permutate_without_delims(&mut stdout, &mut permutator);
} else {
permutate(&mut stdout, &mut permutator);
}
}
},
Err(why) => {
let _ = stderr.write(b"permutate: parse error: ");
match why {
InputError::FileError(path, why) => {
let _ = stderr.write(path.as_bytes());
let _ = stderr.write(b" could not be read: ");
let _ = stderr.write(why.as_bytes());
let _ = stderr.write(b".\n");
}
InputError::NoInputsProvided => {
let _ = stderr.write(b"no input was provided after separator.\n");
},
InputError::NotEnoughInputs => {
let _ = stderr.write(b"not enough inputs were provided.\n");
},
}
let _ = stderr.write(b"Example Usage: permutate 1 2 3 ::: 4 5 6 ::: 1 2 3\n");
exit(1);
}
}
}
fn permutate(stdout: &mut StdoutLock, permutator: &mut Permutator<str>) {
let mut buffer = StdoutBuffer::new();
let mut current_output = permutator.next().unwrap();
{
let mut current_permutation = current_output.iter();
buffer.write(current_permutation.next().unwrap().as_bytes());
buffer.push(b' ');
buffer.write(current_permutation.next().unwrap().as_bytes());
for element in current_permutation {
buffer.push(b' ');
buffer.write(element.as_bytes())
}
}
buffer.push(b'\n');
let permutations_per_buffer = BUFFER_SIZE / buffer.capacity;
let mut counter = 1;
while permutator.next_with_buffer(&mut current_output) {
if counter == permutations_per_buffer {
buffer.write_and_clear(stdout);
counter = 0;
}
let mut current_permutation = current_output.iter();
buffer.write(current_permutation.next().unwrap().as_bytes());
buffer.push(b' ');
buffer.write(current_permutation.next().unwrap().as_bytes());
for element in current_permutation {
buffer.push(b' ');
buffer.write(element.as_bytes())
}
buffer.push(b'\n');
counter += 1;
}
let _ = stdout.write_all(&buffer.data[..]);
}
fn permutate_without_delims(stdout: &mut StdoutLock, permutator: &mut Permutator<str>) {
let mut buffer = StdoutBuffer::new();
let mut current_output = permutator.next().unwrap();
{
let mut permutation = current_output.iter();
buffer.write(permutation.next().unwrap().as_bytes());
buffer.write(permutation.next().unwrap().as_bytes());
for element in permutation { buffer.write(element.as_bytes()); }
}
buffer.push(b'\n');
let permutations_per_buffer = BUFFER_SIZE / buffer.capacity;
let mut counter = 1;
while permutator.next_with_buffer(&mut current_output) {
let mut permutation = current_output.iter();
if counter == permutations_per_buffer {
buffer.write_and_clear(stdout);
counter = 0;
}
buffer.write(permutation.next().unwrap().as_bytes());
buffer.write(permutation.next().unwrap().as_bytes());
for element in permutation { buffer.write(element.as_bytes()); }
buffer.push(b'\n');
counter += 1;
}
let _ = stdout.write_all(&buffer.data[..]);
}