mod opts;
use crate::OptCfg;
use linebreak;
use std::cmp;
pub struct Help {
margin_left: usize,
margin_right: usize,
blocks: Vec<Block>,
}
struct Block {
indent: usize,
margin_left: usize,
margin_right: usize,
bodies: Vec<(usize, String)>,
_spaces: String,
}
impl Help {
pub fn new() -> Self {
Self {
margin_left: 0,
margin_right: 0,
blocks: Vec::<Block>::with_capacity(2),
}
}
pub fn with_margins(margin_left: usize, margin_right: usize) -> Self {
Self {
margin_left: margin_left,
margin_right: margin_right,
blocks: Vec::<Block>::with_capacity(2),
}
}
pub fn add_text(&mut self, text: String) {
self.add_text_with_indent_and_margins(text, 0, 0, 0)
}
pub fn add_text_with_indent(&mut self, text: String, indent: usize) {
self.add_text_with_indent_and_margins(text, indent, 0, 0)
}
pub fn add_text_with_margins(&mut self, text: String, margin_left: usize, margin_right: usize) {
self.add_text_with_indent_and_margins(text, 0, margin_left, margin_right)
}
pub fn add_text_with_indent_and_margins(
&mut self,
text: String,
indent: usize,
margin_left: usize,
margin_right: usize,
) {
let margin_left = self.margin_left + margin_left;
let margin_right = self.margin_right + margin_right;
let max_len = cmp::max(margin_left, indent);
let block = Block {
indent: indent,
margin_left: margin_left,
margin_right: margin_right,
bodies: vec![(0, text)],
_spaces: " ".repeat(max_len),
};
self.blocks.push(block);
}
pub fn add_texts(&mut self, texts: Vec<String>) {
self.add_texts_with_indent_and_margins(texts, 0, 0, 0);
}
pub fn add_texts_with_indent(&mut self, texts: Vec<String>, indent: usize) {
self.add_texts_with_indent_and_margins(texts, indent, 0, 0);
}
pub fn add_texts_with_margins(
&mut self,
texts: Vec<String>,
margin_left: usize,
margin_right: usize,
) {
self.add_texts_with_indent_and_margins(texts, 0, margin_left, margin_right);
}
pub fn add_texts_with_indent_and_margins(
&mut self,
texts: Vec<String>,
indent: usize,
margin_left: usize,
margin_right: usize,
) {
let margin_left = self.margin_left + margin_left;
let margin_right = self.margin_right + margin_right;
let max_len = cmp::max(margin_left, indent);
let block = Block {
indent: indent,
margin_left: margin_left,
margin_right: margin_right,
bodies: texts.into_iter().map(|s| (0, s)).collect(),
_spaces: " ".repeat(max_len),
};
self.blocks.push(block);
}
pub fn add_opts(&mut self, cfgs: &[OptCfg]) {
self.add_opts_with_indent_and_margins(cfgs, 0, 0, 0);
}
pub fn add_opts_with_indent(&mut self, cfgs: &[OptCfg], indent: usize) {
self.add_opts_with_indent_and_margins(cfgs, indent, 0, 0);
}
pub fn add_opts_with_margins(
&mut self,
cfgs: &[OptCfg],
margin_left: usize,
margin_right: usize,
) {
self.add_opts_with_indent_and_margins(cfgs, 0, margin_left, margin_right);
}
pub fn add_opts_with_indent_and_margins(
&mut self,
cfgs: &[OptCfg],
indent: usize,
margin_left: usize,
margin_right: usize,
) {
let mut indent = indent;
let bodies = opts::create_opts_help(cfgs, &mut indent);
let mut max_len = 0;
for (i, _) in &bodies {
max_len = cmp::max(max_len, *i);
}
let margin_left = self.margin_left + margin_left;
let margin_right = self.margin_right + margin_right;
let max_len = cmp::max(max_len, cmp::max(margin_left, indent));
let block = Block {
indent: indent,
margin_left: margin_left,
margin_right: margin_right,
bodies: bodies,
_spaces: " ".repeat(max_len),
};
self.blocks.push(block);
}
pub fn iter(&self) -> HelpIter {
if self.blocks.is_empty() {
return HelpIter {
line_width: 0,
blocks: &self.blocks,
block_iter: BlockIter::empty(),
};
}
let line_width = linebreak::term_cols();
HelpIter {
line_width: line_width,
blocks: &self.blocks,
block_iter: BlockIter::new(&self.blocks[0], line_width),
}
}
pub fn print(&self) {
let mut iter = self.iter();
while let Some(line) = iter.next() {
println!("{}", line);
}
}
}
pub struct HelpIter<'a> {
line_width: usize,
blocks: &'a [Block],
block_iter: BlockIter<'a>,
}
struct BlockIter<'a> {
bodies: &'a [(usize, String)],
index: usize,
indent: &'a str,
margin: &'a str,
line_iter: linebreak::LineIter<'a>,
}
impl Iterator for HelpIter<'_> {
type Item = String;
fn next(&mut self) -> Option<String> {
loop {
if let Some(line) = self.block_iter.next() {
return Some(line);
}
if self.blocks.len() <= 1 {
break;
}
self.blocks = &self.blocks[1..];
self.block_iter = BlockIter::new(&self.blocks[0], self.line_width);
}
None
}
}
impl<'a> BlockIter<'a> {
fn new(block: &'a Block, line_width: usize) -> Self {
let print_width = line_width - block.margin_left - block.margin_right;
if block.bodies.is_empty() || print_width <= block.indent {
return Self::empty();
}
let (indent, text) = &block.bodies[0];
let mut line_iter = linebreak::LineIter::new(&text, print_width);
line_iter.set_indent(&block._spaces[0..(*indent)]);
Self {
bodies: &block.bodies,
index: 0,
indent: &(&block._spaces)[0..block.indent],
margin: &(&block._spaces)[0..block.margin_left],
line_iter: line_iter,
}
}
fn empty() -> Self {
Self {
bodies: &[] as &'a [(usize, String)],
index: 0,
indent: "",
margin: "",
line_iter: linebreak::LineIter::new("", 0),
}
}
}
impl<'a> Iterator for BlockIter<'a> {
type Item = String;
fn next(&mut self) -> Option<String> {
if self.bodies.is_empty() {
return None;
}
loop {
if let Some(mut line) = self.line_iter.next() {
line.insert_str(0, self.margin);
self.line_iter.set_indent(&self.indent);
return Some(line);
}
self.index += 1;
if self.index >= self.bodies.len() {
break;
}
let (indent, text) = &self.bodies[self.index];
self.line_iter.init(&text);
self.line_iter.set_indent(&self.indent[0..(*indent)]);
}
None
}
}
#[cfg(test)]
mod tests_of_help {
use super::*;
#[test]
fn new() {
let help = Help::new();
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, None);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn new_and_add_text_if_one_line_with_zero_wrapping() {
let mut help = Help::new();
help.add_text("abc".to_string());
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("abc".to_string()));
let line = iter.next();
assert_eq!(line, None);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn new_and_add_text_if_one_line_with_wrapping() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols);
text.push_str("123456");
let mut help = Help::new();
help.add_text(text);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("a".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("123456".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn new_add_text_if_multi_lines_with_wrapping() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols);
text.push_str("123456\n");
text.push_str(&"b".repeat(term_cols));
text.push_str("789");
let mut help = Help::new();
help.add_text(text);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("a".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("123456".to_string()));
let line = iter.next();
assert_eq!(line, Some("b".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("789".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn with_margins_and_add_text() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols - 5 - 3);
text.push_str("12345\n");
text.push_str(&"b".repeat(term_cols - 5 - 3));
text.push_str("6789");
let mut help = Help::with_margins(5, 3);
help.add_text(text);
let mut iter = help.iter();
let line = iter.next();
let mut expected = "a".repeat(term_cols - 5 - 3);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 12345".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
let mut expected = "b".repeat(term_cols - 5 - 3);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 6789".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_text_with_margins() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols - 5 - 3);
text.push_str("12345\n");
text.push_str(&"b".repeat(term_cols - 5 - 3));
text.push_str("6789");
let mut help = Help::new();
help.add_text_with_margins(text, 5, 3);
let mut iter = help.iter();
let line = iter.next();
let mut expected = "a".repeat(term_cols - 5 - 3);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 12345".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
let mut expected = "b".repeat(term_cols - 5 - 3);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 6789".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_text_with_indent() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols);
text.push_str("12345\n");
text.push_str(&"b".repeat(term_cols - 8));
text.push_str("6789");
let mut help = Help::new();
help.add_text_with_indent(text, 8);
let mut iter = help.iter();
let line = iter.next();
let expected = "a".repeat(term_cols);
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 12345".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
let mut expected = "b".repeat(term_cols - 8);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 6789".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_text_with_indent_and_margins() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols - 1 - 2);
text.push_str("12345\n");
text.push_str(&"b".repeat(term_cols - 8 - 1 - 2));
text.push_str("6789");
let mut help = Help::new();
help.add_text_with_indent_and_margins(text, 8, 1, 2);
let mut iter = help.iter();
let line = iter.next();
let mut expected = "a".repeat(term_cols - 1 - 2);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 12345".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
let mut expected = "b".repeat(term_cols - 8 - 1 - 2);
expected.insert_str(0, " ");
assert_eq!(line, Some(expected));
let line = iter.next();
let expected = " 6789".to_string();
assert_eq!(line, Some(expected));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_text_if_text_is_empty() {
let mut help = Help::new();
help.add_text("".to_string());
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_text_multiple_times() {
let term_cols = linebreak::term_cols();
let mut text = "a".repeat(term_cols - 4 - 3);
text.push_str(&"b".repeat(term_cols - 4 - 5 - 3));
text.push_str(&"c".repeat(term_cols - 4 - 5 - 3));
let mut help = Help::with_margins(1, 1);
help.add_text_with_indent_and_margins(text, 5, 3, 2);
let mut text = "d".repeat(term_cols - 2 - 2);
text.push_str(&"e".repeat(term_cols - 2 - 5 - 2));
text.push_str(&"f".repeat(term_cols - 2 - 5 - 2));
help.add_text_with_indent_and_margins(text, 5, 1, 1);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some(" ".to_string() + &"a".repeat(term_cols - 7)));
let line = iter.next();
assert_eq!(
line,
Some(" ".to_string() + &"b".repeat(term_cols - 12))
);
let line = iter.next();
assert_eq!(
line,
Some(" ".to_string() + &"c".repeat(term_cols - 12))
);
let line = iter.next();
assert_eq!(line, Some(" ".to_string() + &"d".repeat(term_cols - 4)));
let line = iter.next();
assert_eq!(
line,
Some(" ".to_string() + &"e".repeat(term_cols - 9))
);
let line = iter.next();
assert_eq!(
line,
Some(" ".to_string() + &"f".repeat(term_cols - 9))
);
}
#[test]
fn add_texts_if_array_is_empty() {
let mut help = Help::new();
help.add_texts(Vec::<String>::new());
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, None);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_texts_if_array_has_a_text() {
let term_cols = linebreak::term_cols();
let mut texts = Vec::<String>::new();
let mut text = "a".repeat(term_cols);
text.push_str(&"b".repeat(term_cols));
text.push_str(&"c".repeat(term_cols));
texts.push(text);
let mut help = Help::new();
help.add_texts(texts);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("a".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("b".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("c".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_texts_if_array_has_multiple_texts() {
let term_cols = linebreak::term_cols();
let mut texts = Vec::<String>::new();
let mut text = "a".repeat(term_cols);
text.push_str(&"b".repeat(term_cols));
text.push_str(&"c".repeat(term_cols));
texts.push(text);
let mut text = "d".repeat(term_cols);
text.push_str(&"e".repeat(term_cols));
text.push_str(&"f".repeat(term_cols));
texts.push(text);
let mut help = Help::new();
help.add_texts(texts);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("a".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("b".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("c".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("d".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("e".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some("f".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_texts_with_indent() {
let term_cols = linebreak::term_cols();
let mut texts = Vec::<String>::new();
let mut text = "a".repeat(term_cols);
text.push_str(&"b".repeat(term_cols - 5));
text.push_str(&"c".repeat(term_cols - 5));
texts.push(text);
let mut text = "d".repeat(term_cols);
text.push_str(&"e".repeat(term_cols - 5));
text.push_str(&"f".repeat(term_cols - 5));
texts.push(text);
let mut help = Help::new();
help.add_texts_with_indent(texts, 5);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("a".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(5) + &"b".repeat(term_cols - 5)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(5) + &"c".repeat(term_cols - 5)));
let line = iter.next();
assert_eq!(line, Some("d".repeat(term_cols)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(5) + &"e".repeat(term_cols - 5)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(5) + &"f".repeat(term_cols - 5)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_texts_with_margins() {
let term_cols = linebreak::term_cols();
let mut texts = Vec::<String>::new();
let mut text = "a".repeat(term_cols - 3 - 3);
text.push_str(&"b".repeat(term_cols - 3 - 3));
text.push_str(&"c".repeat(term_cols - 3 - 3));
texts.push(text);
let mut text = "d".repeat(term_cols - 3 - 3);
text.push_str(&"e".repeat(term_cols - 3 - 3));
text.push_str(&"f".repeat(term_cols - 3 - 3));
texts.push(text);
let mut help = Help::with_margins(1, 1);
help.add_texts_with_margins(texts, 2, 2);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"a".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"b".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"c".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"d".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"e".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"f".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_texts_with_indent_and_margins() {
let term_cols = linebreak::term_cols();
let mut texts = Vec::<String>::new();
let mut text = "a".repeat(term_cols - 3 - 3);
text.push_str(&"b".repeat(term_cols - 3 - 5 - 3));
text.push_str(&"c".repeat(term_cols - 3 - 5 - 3));
texts.push(text);
let mut text = "d".repeat(term_cols - 3 - 3);
text.push_str(&"e".repeat(term_cols - 3 - 5 - 3));
text.push_str(&"f".repeat(term_cols - 3 - 5 - 3));
texts.push(text);
let mut help = Help::with_margins(1, 1);
help.add_texts_with_indent_and_margins(texts, 5, 2, 2);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"a".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(8) + &"b".repeat(term_cols - 11)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(8) + &"c".repeat(term_cols - 11)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(3) + &"d".repeat(term_cols - 6)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(8) + &"e".repeat(term_cols - 11)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(8) + &"f".repeat(term_cols - 11)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_no_wrapping() {
use crate::OptCfgParam::*;
let mut help = Help::new();
help.add_opts(&[OptCfg::with([
names(&["foo-bar"]),
desc("This is a description of option."),
])]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some("--foo-bar This is a description of option.".to_string())
);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_wrapping() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts(&[OptCfg::with([
names(&["foo-bar"]),
desc(&("a".repeat(cols - 11) + " bcdef")),
])]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some("--foo-bar ".to_string() + &"a".repeat(cols - 11))
);
let line = iter.next();
assert_eq!(line, Some(" ".to_string() + "bcdef"));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn with_margins_and_add_opts() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::with_margins(4, 2);
help.add_opts(&[OptCfg::with([
names(&["foo-bar"]),
desc(&("a".repeat(cols - 11 - 4 - 2) + " " + &"b".repeat(cols - 11 - 4 - 2) + "ccc")),
])]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some(" --foo-bar ".to_string() + &"a".repeat(cols - 11 - 4 - 2))
);
let line = iter.next();
assert_eq!(
line,
Some(" ".repeat(11 + 4) + &"b".repeat(cols - 11 - 4 - 2))
);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(11 + 4) + "ccc"));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_margins() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts_with_margins(
&[OptCfg::with([
names(&["foo-bar"]),
desc(
&("a".repeat(cols - 11 - 5 - 4) + " " + &"b".repeat(cols - 11 - 5 - 4) + "ccc"),
),
])],
5,
4,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some(" --foo-bar ".to_string() + &"a".repeat(cols - 11 - 5 - 4))
);
let line = iter.next();
assert_eq!(
line,
Some(" ".repeat(11 + 5) + &"b".repeat(cols - 11 - 5 - 4))
);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(11 + 5) + "ccc"));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_margins_by_constructor_and_add_text_with_margins() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::with_margins(4, 2);
help.add_opts_with_margins(
&[OptCfg::with([
names(&["foo-bar"]),
desc(
&("a".repeat(cols - 11 - 5 - 4) + " " + &"b".repeat(cols - 11 - 5 - 4) + "ccc"),
),
])],
1,
2,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some(" --foo-bar ".to_string() + &"a".repeat(cols - 11 - 5 - 4))
);
let line = iter.next();
assert_eq!(
line,
Some(" ".repeat(11 + 5) + &"b".repeat(cols - 11 - 5 - 4))
);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(11 + 5) + "ccc"));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_indent_if_indent_is_longer_than_title() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts_with_indent(
&[OptCfg::with([
names(&["foo-bar"]),
desc(&("a".repeat(cols - 12) + " " + &"b".repeat(cols - 12) + "ccc")),
])],
12,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some("--foo-bar".to_string() + " " + &"a".repeat(cols - 12))
);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(12) + &"b".repeat(cols - 12)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(12) + &"ccc"));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_indent_if_indent_is_shorter_than_title() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts_with_indent(
&[OptCfg::with([
names(&["foo-bar"]),
desc(&("a".repeat(cols))),
])],
10,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("--foo-bar".to_string()));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(10) + &"a".repeat(cols - 10)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(10) + &"a".repeat(10)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_indent_and_margins() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts_with_indent_and_margins(
&[OptCfg::with([
names(&["foo-bar"]),
desc(&("a".repeat(cols))),
])],
6,
4,
2,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some(" --foo-bar".to_string()));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(10) + &"a".repeat(cols - 6 - 4 - 2)));
let line = iter.next();
assert_eq!(line, Some(" ".repeat(10) + &"a".repeat(6 + 4 + 2)));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_if_opts_are_multiple() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts(&[
OptCfg::with([
names(&["foo-bar", "f"]),
has_arg(true),
desc(&("a".repeat(cols - 22) + " " + &"b".repeat(cols - 22) + "ccc")),
arg_in_help("<text>"),
]),
OptCfg::with([
names(&["baz", "b"]),
desc(&("d".repeat(cols - 22) + " " + &"e".repeat(cols - 22) + "fff")),
]),
]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(
line,
Some("--foo-bar, -f <text> ".to_string() + &"a".repeat(cols - 22)),
);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(22) + &"b".repeat(cols - 22)),);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(22) + "ccc"),);
let line = iter.next();
assert_eq!(
line,
Some("--baz, -b ".to_string() + &"d".repeat(cols - 22)),
);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(22) + &"e".repeat(cols - 22)),);
let line = iter.next();
assert_eq!(line, Some(" ".repeat(22) + "fff"),);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_if_names_are_empty_and_store_key_is_specified() {
use crate::OptCfgParam::*;
let mut help = Help::new();
help.add_opts(&[
OptCfg::with([store_key("foo"), desc("description")]),
OptCfg::with([store_key("bar"), names(&["", ""]), desc("description")]),
]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("--foo description".to_string()));
let line = iter.next();
assert_eq!(line, Some(" --bar description".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_if_store_key_is_any_option() {
use crate::OptCfgParam::*;
let mut help = Help::new();
help.add_opts(&[
OptCfg::with([store_key("foo"), desc("description")]),
OptCfg::with([store_key("*"), desc("any option")]),
]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("--foo description".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_if_first_element_of_names_is_any_option() {
use crate::OptCfgParam::*;
let mut help = Help::new();
help.add_opts(&[
OptCfg::with([names(&["foo-bar"]), desc("description")]),
OptCfg::with([names(&["*"]), desc("any option")]),
]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some("--foo-bar description".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_indent_if_indent_is_longer_than_line_width() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts_with_indent(
&[
OptCfg::with([names(&["foo-bar"]), desc("description")]),
OptCfg::with([names(&["baz"]), desc("description")]),
],
cols + 1,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, None);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_with_margins_if_sum_of_margins_are_equal_to_line_width() {
use crate::OptCfgParam::*;
let cols = linebreak::term_cols();
let mut help = Help::new();
help.add_opts_with_margins(
&[
OptCfg::with([names(&["foo-bar"]), desc("description")]),
OptCfg::with([names(&["baz"]), desc("description")]),
],
cols - 1,
1,
);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, None);
let line = iter.next();
assert_eq!(line, None);
}
#[test]
fn add_opts_if_names_contains_empty_strings() {
use crate::OptCfgParam::*;
let mut help = Help::new();
help.add_opts(&[
OptCfg::with([names(&["", "f", "foo-bar", "", ""]), desc("description")]),
OptCfg::with([names(&["b", "", "z", "baz"]), desc("description")]),
]);
let mut iter = help.iter();
let line = iter.next();
assert_eq!(line, Some(" -f, --foo-bar description".to_string()));
let line = iter.next();
assert_eq!(line, Some("-b, -z, --baz description".to_string()));
let line = iter.next();
assert_eq!(line, None);
}
}