From f4009e4c6e4198499b8642b8d6cba0b40f66da20 Mon Sep 17 00:00:00 2001 From: zxlzy <31438870+zxlzy@users.noreply.github.com> Date: Tue, 1 Sep 2020 15:47:22 +0800 Subject: fix(formatting): panic when slice str (#177) * fix panic when slice str * copy code from diskonaut * typo fix --- src/display/components/table.rs | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/display/components/table.rs b/src/display/components/table.rs index 059b5ed..f61886c 100644 --- a/src/display/components/table.rs +++ b/src/display/components/table.rs @@ -1,4 +1,6 @@ use ::std::collections::{BTreeMap, HashMap}; +use ::std::iter::FromIterator; +use ::unicode_width::UnicodeWidthChar; use ::tui::backend::Backend; use ::tui::layout::Rect; @@ -51,11 +53,35 @@ pub struct Table<'a> { breakpoints: BTreeMap, } +fn truncate_iter_to_unicode_width(iter: Input, width: usize) -> Collect +where + Input: Iterator, + Collect: FromIterator, +{ + let mut chunk_width = 0; + iter.take_while(|ch| { + chunk_width += ch.width().unwrap_or(0); + chunk_width <= width + }) + .collect() +} + fn truncate_middle(row: &str, max_length: u16) -> String { - if row.len() as u16 > max_length { - let first_slice = &row[0..(max_length as usize / 2) - 2]; - let second_slice = &row[(row.len() - (max_length / 2) as usize + 2)..row.len()]; - format!("{}[..]{}", first_slice, second_slice) + if max_length < 6 { + truncate_iter_to_unicode_width(row.chars(), max_length as usize) + } else if row.len() as u16 > max_length { + let split_point = (max_length as usize / 2) - 2; + let first_slice = truncate_iter_to_unicode_width::<_, String>(row.chars(), split_point); + let second_slice = + truncate_iter_to_unicode_width::<_, Vec<_>>(row.chars().rev(), split_point) + .into_iter() + .rev() + .collect::(); + if max_length % 2 == 0 { + format!("{}[..]{}", first_slice, second_slice) + } else { + format!("{}[..]{}", first_slice, second_slice) + } } else { row.to_string() } -- cgit v1.2.3