use std::convert::TryInto;
use std::io::{BufWriter, Write};
use std::iter::FromIterator;
use crate::config::Config;
use crate::writeable::Writeable;
use crate::writer::WriteReceiver;
#[derive(Debug)]
pub struct Choice {
pub start: isize,
pub end: isize,
pub kind: ChoiceKind,
negative_index: bool,
reversed: bool,
}
#[derive(Debug, PartialEq)]
pub enum ChoiceKind {
Single,
RustExclusiveRange,
RustInclusiveRange,
ColonRange,
}
impl Choice {
pub fn new(start: isize, end: isize, kind: ChoiceKind) -> Self {
let negative_index = start < 0 || end < 0;
let reversed = end < start && !(start >= 0 && end < 0);
Choice {
start,
end,
kind,
negative_index,
reversed,
}
}
pub fn print_choice<W: Write>(
&self,
line: &String,
config: &Config,
handle: &mut BufWriter<W>,
) {
if config.opt.character_wise {
let line_chars = line[0..line.len() - 1].chars();
self.print_choice_generic(line_chars, config, handle);
} else {
let line_iter = config
.separator
.split(line)
.filter(|s| !s.is_empty() || config.opt.non_greedy);
self.print_choice_generic(line_iter, config, handle);
}
}
pub fn is_reverse_range(&self) -> bool {
self.reversed
}
pub fn has_negative_index(&self) -> bool {
self.negative_index
}
fn print_choice_generic<W, T, I>(&self, mut iter: I, config: &Config, handle: &mut BufWriter<W>)
where
W: Write,
T: Writeable + Copy,
I: Iterator<Item = T>,
{
if self.is_reverse_range() && !self.has_negative_index() {
self.print_choice_reverse(iter, config, handle);
} else if self.has_negative_index() {
self.print_choice_negative(iter, config, handle);
} else {
if self.start > 0 {
iter.nth((self.start - 1).try_into().unwrap());
}
let range = self.end.checked_sub(self.start).unwrap();
Choice::print_choice_loop_max_items(iter, config, handle, range);
}
}
fn print_choice_loop<W, T, I>(iter: I, config: &Config, handle: &mut BufWriter<W>)
where
W: Write,
T: Writeable + Copy,
I: Iterator<Item = T>,
{
Choice::print_choice_loop_max_items(iter, config, handle, isize::max_value());
}
fn print_choice_loop_max_items<W, T, I>(
iter: I,
config: &Config,
handle: &mut BufWriter<W>,
max_items: isize