From 19f08a0eeb95d20c9cc303279b3e58f9bf122b9a Mon Sep 17 00:00:00 2001 From: rabite Date: Mon, 27 Jan 2020 02:16:31 +0100 Subject: changed sized_string() to return string slice instaed of allocating --- src/file_browser.rs | 2 +- src/term.rs | 28 +++++++++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/file_browser.rs b/src/file_browser.rs index 0d0052b..1ed031e 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -1240,7 +1240,7 @@ impl Widget for FileBrowser { let pretty_path = format!("{}/{}{}", path, &color, name ); let sized_path = crate::term::sized_string(&pretty_path, xsize); - Ok(sized_path) + Ok(sized_path.to_string()) } fn render_footer(&self) -> HResult { let xsize = term::xsize_u(); diff --git a/src/term.rs b/src/term.rs index d13ff29..b35dc37 100644 --- a/src/term.rs +++ b/src/term.rs @@ -220,15 +220,25 @@ pub fn cell_ratio() -> HResult { Ok(ratio) } -pub fn sized_string(string: &str, xsize: u16) -> String { - string.chars().fold("".to_string(), |acc, ch| { - let width: usize = unicode_width::UnicodeWidthStr::width(acc.as_str()); - if width + 1 >= xsize as usize { - acc - } else { - acc + &ch.to_string() - } - }) +pub fn sized_string(string: &str, xsize: u16) -> &str { + let len = string.char_indices() + .map(|(i, ch)| { + if ch.is_ascii() { + (i, 1) + } else { + (i, UnicodeWidthChar::width(ch).unwrap_or(0)) + } + }) + .scan(0, |slen, (i, chlen)| { + *slen += chlen; + Some((i, *slen)) + }) + .take_while(|(_, slen)| slen < &(xsize as usize)) + .map(|(i,_)| i) + .last() + .unwrap_or(0); + + &string[0..len+1] } #[derive(Debug)] -- cgit v1.2.3