use crate::{ch, ChUnit, UnicodeString};
impl UnicodeString {
pub fn insert_char_at_display_col(
&self,
display_col: ChUnit,
chunk: &str,
) -> Option<(
/* new string */ UnicodeString,
/* display width of chunk */ ChUnit,
)> {
let mut acc = Vec::with_capacity(self.len() + 1);
for item in self.vec_segment.iter() {
acc.push(item.string.as_str());
}
let maybe_logical_index = self.logical_index_at_display_col_index(display_col);
match maybe_logical_index {
Some(logical_index) => acc.insert(logical_index, chunk),
None => acc.push(chunk),
};
let new_string = acc.join("");
let new_unicode_string = UnicodeString::from(new_string);
let chunk_display_width: ChUnit = ch!(UnicodeString::str_display_width(chunk));
Some((new_unicode_string, chunk_display_width))
}
pub fn delete_char_at_display_col(
&self,
display_col: ChUnit,
) -> Option<UnicodeString> {
if self.len() == 0 {
return None;
}
if self.len() == 1 {
return Some(UnicodeString::default());
}
let split_logical_index = self.logical_index_at_display_col_index(display_col)?;
let max_logical_index = self.len();
let mut vec_left = Vec::with_capacity(self.len());
let mut str_left_unicode_width = ch!(0);
{
for logical_idx in 0..split_logical_index {
let segment = self.at_logical_index(logical_idx)?;
vec_left.push(segment.string.as_str());
str_left_unicode_width += segment.unicode_width;
}
}
let skip_split_logical_index = split_logical_index + 1; let mut vec_right = Vec::with_capacity(self.len());
let mut str_right_unicode_width = ch!(0);
{
for logical_idx in skip_split_logical_index..max_logical_index {
let seg_at_logical_idx = self.at_logical_index(logical_idx)?;
vec_right.push(seg_at_logical_idx.string.as_str());
str_right_unicode_width += seg_at_logical_idx.unicode_width;
}
}
vec_left.append(&mut vec_right);
let new_string = vec_left.join("");
Some(UnicodeString::from(new_string))
}
pub fn split_at_display_col(
&self,
display_col: ChUnit,
) -> Option<(UnicodeString, UnicodeString)> {
let split_logical_index = self.logical_index_at_display_col_index(display_col)?;
let max_logical_index = self.len();
let mut vec_left = Vec::with_capacity(self.len());
let mut str_left_unicode_width = ch!(0);
{
for logical_idx in 0..split_logical_index {
let segment = self.at_logical_index(logical_idx)?;
vec_left.push(segment.string.as_ref());
str_left_unicode_width += segment.unicode_width;
}
}
let mut vec_right = Vec::with_capacity(self.len());
let mut str_right_unicode_width = ch!(0);
{
for logical_idx in split_logical_index..max_logical_index {
let seg_at_logical_idx = self.at_logical_index(logical_idx)?;
vec_right.push(seg_at_logical_idx.string.as_ref());
str_right_unicode_width += seg_at_logical_idx.unicode_width;
}
}
if str_right_unicode_width > ch!(0) || str_left_unicode_width > ch!(0) {
Some((
UnicodeString::from(vec_left.join("")),
UnicodeString::from(vec_right.join("")),
))
} else {
None
}
}
}