use std::iter::FromIterator;
use crate::utils::arrangement::ColumnDisplayInfo;
pub fn split_line(line: &str, info: &ColumnDisplayInfo, delimiter: char) -> Vec<String> {
let mut lines = Vec::new();
let content_width = info.content_width();
let mut elements = line
.split(delimiter)
.map(|element| element.to_string())
.collect::<Vec<String>>();
elements.reverse();
let mut current_line = String::new();
while let Some(next) = elements.pop() {
let current_length = current_line.chars().count();
let next_length = next.chars().count();
let mut added_length = next_length + current_length;
if !current_line.is_empty() {
added_length += 1;
}
let mut remaining_width = content_width as i32 - current_line.chars().count() as i32;
if !current_line.is_empty() {
remaining_width -= 1;
}
if added_length as u16 <= content_width {
if !current_line.is_empty() {
current_line.push(delimiter);
}
current_line += &next;
current_line = check_if_full(&mut lines, content_width, current_line);
continue;
}
if !current_line.is_empty() && remaining_width <= MIN_FREE_CHARS {
elements.push(next);
lines.push(current_line);
current_line = String::new();
continue;
}
if next_length as u16 > content_width {
let mut next: Vec<char> = next.chars().collect();
if !current_line.is_empty() {
current_line.push(delimiter);
}
let remaining = next.split_off((remaining_width) as usize);
current_line += &String::from_iter(next);
elements.push(String::from_iter(remaining));
lines.push(current_line);
current_line = String::new();
continue;
}
lines.push(current_line);
current_line = next.to_string();
current_line = check_if_full(&mut lines, content_width, current_line);
}
if !current_line.is_empty() {
lines.push(current_line);
}
lines
}
const MIN_FREE_CHARS: i32 = 2;
fn check_if_full(lines: &mut Vec<String>, content_width: u16, current_line: String) -> String {
if current_line.chars().count() as i32 > content_width as i32 - MIN_FREE_CHARS {
lines.push(current_line);
return String::new();
}
current_line
}