pub mod string {
pub trait Justify {
fn justify_line(&self, width: usize) -> String;
}
impl Justify for &'static str {
fn justify_line(&self, width: usize) -> String {
let trimmed = self.trim() ;
let len = trimmed.len();
if len >= width { return self.to_string(); };
let difference = width - len;
let iter = trimmed.split_whitespace();
let spaces = iter.count() - 1;
let mut iter = trimmed.split_whitespace().peekable();
if spaces == 0 { return self.to_string(); }
let mut obj = String::with_capacity(width);
let div = difference / spaces;
let mut remainder = difference % spaces;
loop {
match iter.next() {
Some(x) => {
obj.push_str( x );
let val = if remainder > 0 {
remainder = remainder - 1;
div + 1
} else { div };
for _ in 0..val+1 {
match &iter.peek() { &Some(_) => {
obj.push_str( " " );
},
&None => {},
}
}
},
None => { break },
}
}
obj
}
}
pub trait SubstMarks {
fn subst_marks(&self, marks: Vec<usize>, chr: &'static str) -> String;
}
impl SubstMarks for &'static str {
fn subst_marks(&self, marks: Vec<usize>, chr: &'static str) -> String {
let mut output = String::with_capacity(self.len());
for x in 0..self.len() {
if marks.contains(&x) {
output.push_str(chr)
} else {
output.push(self[x..x+1].chars().next().unwrap())
}
}
output
}
}
pub trait AfterWhitespace {
fn seek_end_of_whitespace(&self, offset: usize) -> Option<usize>;
}
impl AfterWhitespace for &'static str {
fn seek_end_of_whitespace(&self, offset: usize) -> Option<usize> {
if self.len() < offset { return None; };
let mut seeker = self[offset..self.len()].chars();
let mut val = None;
let mut indx = 0;
loop {
match seeker.next() {
Some(x) => {
if x.ne(&" ".chars().next().unwrap()) {
val = Some(indx);
break;
}
indx += 1;
},
None => { break; },
}
}
val
}
}
pub trait WordWrap {
fn word_wrap(&self, width: usize) -> String;
}
impl WordWrap for &'static str {
fn word_wrap(&self, width: usize) -> String {
let mut markers = vec![];
fn wordwrap(t: &'static str, chunk: usize, offset: usize, mrkrs: &mut Vec<usize>) -> String {
match t[offset..*vec![offset+chunk,t.len()].iter().min().unwrap()].rfind("\n") {
None => {
match t[offset..*vec![offset+chunk,t.len()].iter().min().unwrap()].rfind(" ") {
Some(x) => {
let mut eows = x; if offset+chunk < t.len() { match t.seek_end_of_whitespace(offset+x) {
Some(a) => {
if a.ne(&0) {
eows = x+a-1;
}
},
None => {},
}
}
if offset+chunk < t.len() { if !["\n".chars().next().unwrap(), " ".chars().next().unwrap()].contains(
&t[offset+eows+1..offset+eows+2].chars().next().unwrap()
) {
mrkrs.push(offset+eows)
}
};
wordwrap(t, chunk, offset+eows+1, mrkrs)
},
None => {
if offset+chunk < t.len() { wordwrap(t, chunk, offset+1, mrkrs) } else {
use string::SubstMarks;
return t.subst_marks(mrkrs.to_vec(), "\n")
}
},
}
},
Some(x) => {
wordwrap(t, chunk, offset+x+1, mrkrs)
},
}
};
wordwrap(self, width+1, 0, &mut markers)
}
}
}