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