use crate::buf::opt::{BufferOptions, FileFormatOption};
use crate::defaults::ascii::AsciiControlCodeFormatter;
use ascii::AsciiChar;
use compact_str::CompactString;
use icu::properties::{CodePointMapData, props::EastAsianWidth};
pub fn char_width(opt: &BufferOptions, c: char) -> usize {
if c.is_ascii_control() {
let ac = AsciiChar::from_ascii(c).unwrap();
match ac {
AsciiChar::Tab => opt.tab_stop() as usize,
AsciiChar::LineFeed => 0,
AsciiChar::CarriageReturn => {
if opt.file_format() == FileFormatOption::Unix {
let ascii_formatter = AsciiControlCodeFormatter::from(ac);
format!("{ascii_formatter}").len()
} else {
0
}
}
_ => {
let ascii_formatter = AsciiControlCodeFormatter::from(ac);
format!("{ascii_formatter}").len()
}
}
} else {
match CodePointMapData::<EastAsianWidth>::new().get(c) {
EastAsianWidth::Wide => 2_usize,
EastAsianWidth::Fullwidth => 2_usize,
EastAsianWidth::Halfwidth => 1_usize,
EastAsianWidth::Narrow => 1_usize,
EastAsianWidth::Ambiguous => 1_usize,
EastAsianWidth::Neutral => 1_usize,
_ => 1_usize,
}
}
}
pub fn char_symbol(opt: &BufferOptions, c: char) -> CompactString {
if c.is_ascii_control() {
let ac = AsciiChar::from_ascii(c).unwrap();
match ac {
AsciiChar::Tab => {
CompactString::from(" ".repeat(opt.tab_stop() as usize))
}
AsciiChar::LineFeed => CompactString::new(""),
AsciiChar::CarriageReturn => {
if opt.file_format() == FileFormatOption::Unix {
let ascii_formatter = AsciiControlCodeFormatter::from(ac);
CompactString::from(format!("{ascii_formatter}"))
} else {
CompactString::new("")
}
}
_ => {
let ascii_formatter = AsciiControlCodeFormatter::from(ac);
CompactString::from(format!("{ascii_formatter}"))
}
}
} else {
CompactString::from(c.to_string())
}
}
pub fn str_width(opt: &BufferOptions, s: &str) -> usize {
s.chars().map(|c| char_width(opt, c)).sum()
}
pub fn str_symbols(opt: &BufferOptions, s: &str) -> CompactString {
s.chars().map(|c| char_symbol(opt, c)).fold(
CompactString::with_capacity(s.len()),
|mut init_symbol, mut symbol| {
init_symbol.push_str(symbol.as_mut_str());
init_symbol
},
)
}