use std::str::CharIndices;
use std::io::Result as IoResult;
use std::io::Write;
use super::action::{IFlagAction, ParseResult};
use super::action::ParseResult::Help;
pub struct HelpAction;
impl IFlagAction for HelpAction {
fn parse_flag(&self) -> ParseResult {
return Help;
}
}
struct WordsIter<'a> {
data: &'a str,
iter: CharIndices<'a>,
}
impl<'a> WordsIter<'a> {
fn new(data: &'a str) -> WordsIter<'a> {
return WordsIter {
data: data,
iter: data.char_indices(),
};
}
}
impl<'a> Iterator for WordsIter<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<&'a str> {
let word_start;
loop {
let (idx, ch) = match self.iter.next() {
None => return None,
Some((idx, ch)) => ((idx, ch)),
};
match ch {
' ' | '\t' | '\r' | '\n' => continue,
_ => {
word_start = idx;
break;
}
}
}
loop {
let (idx, ch) = match self.iter.next() {
None => break,
Some((idx, ch)) => ((idx, ch)),
};
match ch {
' ' | '\t' | '\r' | '\n' => {
return Some(&self.data[word_start..idx]);
}
_ => continue,
}
}
return Some(&self.data[word_start..self.data.len()]);
}
}
pub fn wrap_text(buf: &mut Write, data: &str, width: usize, indent: usize)
-> IoResult<()>
{
let mut witer = WordsIter::new(data);
let mut off = indent;
match witer.next() {
None => {
return Ok(());
}
Some(word) => {
try!(buf.write(word.as_bytes()));
off += word.len();
}
}
for word in witer {
if off + word.len() + 1 > width {
try!(buf.write(b"\n"));
for _ in 0..indent {
try!(buf.write(b" "));
}
off = indent;
} else {
try!(buf.write(b" "));
off += 1;
}
try!(buf.write(word.as_bytes()));
off += word.len();
}
return Ok(());
}