use unicode_segmentation::UnicodeSegmentation;
#[cfg(feature = "fish")]
use crate::widecharwidth::char_width;
#[inline]
pub fn str_width(s: &str) -> usize {
UnicodeSegmentation::graphemes(s, true)
.map(grapheme_width)
.sum()
}
#[inline]
pub fn grapheme_width(g: &str) -> usize {
if g.contains('\u{200d}') {
2
} else {
#[cfg(feature = "fish")]
{
use unicode_width::UnicodeWidthChar;
g.chars()
.map(|c| {
if let Some(w) = char_width(c) {
w
} else {
UnicodeWidthChar::width(c).unwrap_or(0)
}
})
.sum()
}
#[cfg(not(feature = "fish"))]
{
use unicode_width::UnicodeWidthStr;
UnicodeWidthStr::width(g)
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_str_width() {
assert_eq!(str_width("aaa"), 3);
assert_eq!(str_width("a"), 1);
assert_eq!(str_width("💎💎"), 4);
assert_eq!(str_width("💎"), 2);
assert_eq!(str_width("大大"), 4);
assert_eq!(str_width("大"), 2);
assert_eq!(str_width("🇨🇦🇨🇦"), 4);
assert_eq!(str_width("🇨🇦"), 2);
#[cfg(feature = "fish")]
{
assert_eq!(str_width("हिन्दी"), 3);
assert_eq!(str_width("हि"), 1);
}
#[cfg(not(feature = "fish"))]
{
assert_eq!(str_width("हिन्दी"), 5);
assert_eq!(str_width("हि"), 2);
}
}
#[test]
fn test_grapheme_width() {
assert_eq!(grapheme_width("a"), 1);
assert_eq!(grapheme_width("💎"), 2);
assert_eq!(grapheme_width("大"), 2);
assert_eq!(grapheme_width("🇨🇦"), 2);
#[cfg(feature = "fish")]
assert_eq!(grapheme_width("हि"), 1);
#[cfg(not(feature = "fish"))]
assert_eq!(grapheme_width("हि"), 2);
}
}