Skip to main content

zero_copy_pads/
width.rs

1pub use unicode_width::{UnicodeWidthChar, UnicodeWidthStr, UNICODE_VERSION};
2
3use core::fmt::{Display, Error, Formatter};
4use derive_more::{AsMut, AsRef, Deref, DerefMut, From};
5
6/// Value that has width.
7pub trait Width: Display {
8    /// Get width of the value.
9    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}