ui: make word_break an iter

embed
Manos Pitsidianakis 2019-04-26 21:33:11 +03:00
parent b104a71544
commit 72d347eb6b
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 58 additions and 45 deletions

View File

@ -575,7 +575,7 @@ pub fn copy_area_with_break(
) -> Pos {
if !is_valid_area!(dest) || !is_valid_area!(src) {
eprint!("{}:{}_{}: ", file!(), line!(), column!());
eprintln!(
eprintln!(
"BUG: Invalid areas in copy_area:\n src: {:?}\n dest: {:?}",
src, dest
);
@ -623,7 +623,7 @@ eprintln!(
pub fn copy_area(grid_dest: &mut CellBuffer, grid_src: &CellBuffer, dest: Area, src: Area) -> Pos {
if !is_valid_area!(dest) || !is_valid_area!(src) {
eprint!("{}:{}_{}: ", file!(), line!(), column!());
eprintln!(
eprintln!(
"BUG: Invalid areas in copy_area:\n src: {:?}\n dest: {:?}",
src, dest
);
@ -641,7 +641,7 @@ eprintln!(
if src_x >= cols || src_y >= rows {
if cfg!(debug_assertions) {
eprint!("{}:{}_{}: ", file!(), line!(), column!());
eprintln!("DEBUG: src area outside of grid_src in copy_area",);
eprintln!("DEBUG: src area outside of grid_src in copy_area",);
}
return upper_left!(dest);
}
@ -681,14 +681,14 @@ pub fn change_colors(grid: &mut CellBuffer, area: Area, fg_color: Color, bg_colo
{
if cfg!(debug_assertions) {
eprint!("{}:{}_{}: ", file!(), line!(), column!());
eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area);
eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area);
}
return;
}
if !is_valid_area!(area) {
if cfg!(debug_assertions) {
eprint!("{}:{}_{}: ", file!(), line!(), column!());
eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area);
eprintln!("BUG: Invalid area in change_colors:\n area: {:?}", area);
}
return;
}
@ -741,7 +741,7 @@ pub fn write_string_to_grid(
{
if cfg!(debug_assertions) {
eprint!("{}:{}_{}: ", file!(), line!(), column!());
eprintln!(" Invalid area with string {} and area {:?}", s, area);
eprintln!(" Invalid area with string {} and area {:?}", s, area);
}
return (x, y);
}
@ -770,45 +770,6 @@ eprintln!(" Invalid area with string {} and area {:?}", s, area);
(x, y)
}
pub fn word_break_string(mut s: &str, width: usize) -> Vec<&str> {
let mut ret: Vec<&str> = Vec::with_capacity(16);
loop {
if s.is_empty() {
break;
}
s = s.trim_start_matches(|c| c == ' ');
if s.starts_with('\n') {
ret.push(&s[0..0]);
s = &s["\n".len()..];
continue;
}
if let Some(next_idx) = s.as_bytes().iter().position(|&c| c == b'\n') {
if next_idx <= width {
ret.push(&s[..next_idx]);
s = &s[next_idx + 1..];
continue;
}
}
let graphemes = s.graphemes_indices();
if graphemes.len() > width {
// use grapheme indices and find position of " " graphemes
if let Some(next_idx) = graphemes[..width].iter().rposition(|(_, g)| *g == " ") {
let next_idx = graphemes[next_idx].0;
ret.push(&s[..next_idx]);
s = &s[next_idx + 1..];
} else {
ret.push(&s[..width]);
s = &s[width..];
}
} else {
ret.push(s);
break;
}
}
ret
}
/// Completely clear an `Area` with an empty char and the terminal's default colors.
pub fn clear_area(grid: &mut CellBuffer, area: Area) {
if !is_valid_area!(area) {

View File

@ -39,6 +39,58 @@ pub trait Graphemes: UnicodeSegmentation + CodePointsIter {
impl Graphemes for str {}
pub struct WordBreakIter<'s> {
input: &'s str,
width: usize,
}
impl<'s> Iterator for WordBreakIter<'s> {
type Item = &'s str;
fn next(&mut self) -> Option<&'s str> {
if self.input.is_empty() {
return None;
}
self.input = self.input.trim_start_matches(|c| c == ' ');
if self.input.starts_with('\n') {
let ret = &self.input[0..];
self.input = &self.input["\n".len()..];
return Some(ret);
}
if let Some(next_idx) = self.input.as_bytes().iter().position(|&c| c == b'\n') {
if next_idx <= self.width {
let ret = &self.input[..next_idx];
self.input = &self.input[next_idx + 1..];
return Some(ret);
}
}
let graphemes = UnicodeSegmentation::grapheme_indices(self.input, true)
.take(self.width)
.collect::<Vec<(usize, &str)>>();
if graphemes.len() == self.width {
// use grapheme indices and find position of " " graphemes
if let Some(next_idx) = graphemes.iter().rposition(|(_, g)| *g == " ") {
let next_idx = graphemes[next_idx].0;
let ret = &self.input[..next_idx];
self.input = &self.input[next_idx + 1..];
return Some(&self.input[..next_idx]);
} else {
let ret = &self.input[..self.width];
self.input = &self.input[self.width..];
return Some(ret);
}
} else {
let ret = self.input;
self.input = &self.input[self.input.len() - 1..];
return Some(ret);
}
}
}
pub fn word_break_string(mut s: &str, width: usize) -> Vec<&str> {
let iter = WordBreakIter { input: s, width };
iter.collect()
}
//#[derive(PartialEq)]
//enum Property {
// CR,