1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
pub use unicode_width::{UnicodeWidthChar, UnicodeWidthStr, UNICODE_VERSION};
use core::fmt::{Display, Error, Formatter};
use derive_more::{AsMut, AsRef, Deref, DerefMut, From};
pub trait Width: Display {
fn width(&self) -> usize;
}
impl Width for str {
fn width(&self) -> usize {
UnicodeWidthStr::width(self)
}
}
impl Width for &str {
fn width(&self) -> usize {
UnicodeWidthStr::width(*self)
}
}
#[cfg(feature = "std")]
impl Width for String {
fn width(&self) -> usize {
UnicodeWidthStr::width(self.as_str())
}
}
impl<X: Width + Sized> Width for &X {
fn width(&self) -> usize {
X::width(*self)
}
}
macro_rules! wrapper {
(
$(#[$attributes:meta])*
$name:ident = $get_width:expr
) => {
$(#[$attributes])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, AsMut, AsRef, Deref, DerefMut, From)]
pub struct $name<Inner: AsRef<str>>(Inner);
impl<Inner: AsRef<str>> $name<Inner> {
#[doc = "Extract the inner value."]
pub fn into_inner(self) -> Inner {
self.0
}
#[doc = "Get reference to inner value."]
pub fn as_inner(&self) -> &'_ Inner {
self.as_ref()
}
#[doc = "Get reference to inner `str`."]
pub fn as_str(&self) -> &'_ str {
self.as_ref()
}
}
impl<Inner: AsRef<str>> Width for $name<Inner> {
fn width(&self) -> usize {
$get_width(self.as_str())
}
}
impl<Inner: AsRef<str>> AsRef<str> for $name<Inner> {
fn as_ref(&self) -> &'_ str {
self.as_inner().as_ref()
}
}
impl<Inner: AsRef<str>> Display for $name<Inner> {
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error> {
write!(formatter, "{}", self.as_str())
}
}
};
}
wrapper! {
#[doc = "Treat [`UnicodeWidthStr::width`] as width."]
UnicodeWidth = UnicodeWidthStr::width
}
wrapper! {
#[doc = "Treat [`UnicodeWidthStr::width_cjk`] as width."]
UnicodeWidthCjk = UnicodeWidthStr::width_cjk
}
wrapper! {
#[doc = "Treat character count as width."]
CharCount = |x: &str| x.chars().count()
}
wrapper! {
#[doc = "Treat `str::len` as width."]
Len = str::len
}