Skip to main content

textos/unicode/char/
core_impls.rs

1// textos::string::char::core_impls
2
3use super::{Char16, Char24, Char32, Char7, Char8, NonMaxU8, NonSurrogateU16};
4use crate::error::{TextosError, TextosResult as Result};
5use core::fmt;
6use devela::codegen::paste;
7
8/* Default, Display, Debug */
9
10macro_rules! core_impls {
11    ($name:ident: $( $bits:literal + $default:expr ),+ ) => {
12        $( core_impls![@$name: $bits + $default]; )+
13    };
14    (@$name:ident: $bits:literal + $default:expr) => { paste! {
15        /// Returns the default value of `\x00` (nul character).
16        impl Default for [<$name $bits>] {
17            #[inline]
18            fn default() -> Self { $default }
19        }
20        impl fmt::Display for [<$name $bits>] {
21            #[inline]
22            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23                write!(f, "{}", self.to_char())
24            }
25        }
26        impl fmt::Debug for [<$name $bits>] {
27            #[inline]
28            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29                write!(f, "{:?}", self.to_char())
30            }
31        }
32        impl fmt::Binary for [<$name $bits>] {
33            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34                fmt::Binary::fmt(&self.to_u32(), f)
35            }
36        }
37        impl fmt::LowerHex for [<$name $bits>] {
38            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39                fmt::LowerHex::fmt(&self.to_u32(), f)
40            }
41        }
42        impl fmt::UpperHex for [<$name $bits>] {
43            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44                fmt::UpperHex::fmt(&self.to_u32(), f)
45            }
46        }
47        impl fmt::Octal for [<$name $bits>] {
48            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49                fmt::Octal::fmt(&self.to_u32(), f)
50            }
51        }
52    }};
53}
54core_impls![Char:
55    7+Self(NonMaxU8::new(0).unwrap()),
56    8+Self(0),
57    16+Self(NonSurrogateU16::new(0).unwrap()),
58    24+Self{ hi: NonMaxU8::new(0).unwrap(), mi: 0, lo: 0 },
59    32+Self('\x00')
60];
61
62/* From Char7 */
63
64impl From<Char7> for Char8 {
65    #[inline]
66    fn from(c: Char7) -> Char8 {
67        c.to_char8()
68    }
69}
70impl From<Char7> for Char16 {
71    #[inline]
72    fn from(c: Char7) -> Char16 {
73        c.to_char16()
74    }
75}
76impl From<Char7> for Char24 {
77    #[inline]
78    fn from(c: Char7) -> Char24 {
79        c.to_char24()
80    }
81}
82impl From<Char7> for Char32 {
83    #[inline]
84    fn from(c: Char7) -> Char32 {
85        c.to_char32()
86    }
87}
88impl From<Char7> for char {
89    #[inline]
90    fn from(c: Char7) -> char {
91        c.to_char()
92    }
93}
94
95/* From Char8 */
96
97impl TryFrom<Char8> for Char7 {
98    type Error = TextosError;
99    #[inline]
100    fn try_from(c: Char8) -> Result<Char7> {
101        c.try_to_char7()
102    }
103}
104impl From<Char8> for Char16 {
105    #[inline]
106    fn from(c: Char8) -> Char16 {
107        c.to_char16()
108    }
109}
110impl From<Char8> for Char24 {
111    #[inline]
112    fn from(c: Char8) -> Char24 {
113        c.to_char24()
114    }
115}
116impl From<Char8> for Char32 {
117    #[inline]
118    fn from(c: Char8) -> Char32 {
119        c.to_char32()
120    }
121}
122impl From<Char8> for char {
123    #[inline]
124    fn from(c: Char8) -> char {
125        c.to_char()
126    }
127}
128
129/* From Char16 */
130
131impl TryFrom<Char16> for Char7 {
132    type Error = TextosError;
133    #[inline]
134    fn try_from(c: Char16) -> Result<Char7> {
135        c.try_to_char7()
136    }
137}
138impl TryFrom<Char16> for Char8 {
139    type Error = TextosError;
140    #[inline]
141    fn try_from(c: Char16) -> Result<Char8> {
142        c.try_to_char8()
143    }
144}
145impl From<Char16> for Char24 {
146    #[inline]
147    fn from(c: Char16) -> Char24 {
148        c.to_char24()
149    }
150}
151impl From<Char16> for Char32 {
152    #[inline]
153    fn from(c: Char16) -> Char32 {
154        #[cfg(not(feature = "unsafe"))]
155        return c.to_char32();
156
157        // SAFETY: we've already checked we contain a valid char.
158        #[cfg(feature = "unsafe")]
159        return unsafe { Char32(char::from_u32_unchecked(c.0.get() as u32)) };
160    }
161}
162impl From<Char16> for char {
163    #[inline]
164    fn from(c: Char16) -> char {
165        c.to_char()
166    }
167}
168
169/* From Char24 */
170
171impl TryFrom<Char24> for Char7 {
172    type Error = TextosError;
173    #[inline]
174    fn try_from(c: Char24) -> Result<Char7> {
175        c.try_to_char7()
176    }
177}
178impl TryFrom<Char24> for Char8 {
179    type Error = TextosError;
180    #[inline]
181    fn try_from(c: Char24) -> Result<Char8> {
182        c.try_to_char8()
183    }
184}
185impl TryFrom<Char24> for Char16 {
186    type Error = TextosError;
187    #[inline]
188    fn try_from(c: Char24) -> Result<Char16> {
189        c.try_to_char16()
190    }
191}
192impl From<Char24> for Char32 {
193    #[inline]
194    fn from(c: Char24) -> Char32 {
195        #[cfg(not(feature = "unsafe"))]
196        return c.to_char32();
197
198        // SAFETY: we've already checked we contain a valid char.
199        #[cfg(feature = "unsafe")]
200        return unsafe { Char32(char::from_u32_unchecked(c.to_u32())) };
201    }
202}
203impl From<Char24> for char {
204    #[inline]
205    fn from(c: Char24) -> char {
206        c.to_char()
207    }
208}
209
210/* From Char32 */
211
212impl TryFrom<Char32> for Char7 {
213    type Error = TextosError;
214    #[inline]
215    fn try_from(c: Char32) -> Result<Char7> {
216        c.try_to_char7()
217    }
218}
219impl TryFrom<Char32> for Char8 {
220    type Error = TextosError;
221    #[inline]
222    fn try_from(c: Char32) -> Result<Char8> {
223        c.try_to_char8()
224    }
225}
226impl TryFrom<Char32> for Char16 {
227    type Error = TextosError;
228    #[inline]
229    fn try_from(c: Char32) -> Result<Char16> {
230        c.try_to_char16()
231    }
232}
233impl From<Char32> for Char24 {
234    #[inline]
235    fn from(c: Char32) -> Char24 {
236        c.to_char24()
237    }
238}
239impl From<Char32> for char {
240    #[inline]
241    fn from(c: Char32) -> char {
242        c.to_char()
243    }
244}
245
246/* From char */
247
248impl TryFrom<char> for Char7 {
249    type Error = TextosError;
250    #[inline]
251    fn try_from(c: char) -> Result<Char7> {
252        Char7::try_from_char(c)
253    }
254}
255impl TryFrom<char> for Char8 {
256    type Error = TextosError;
257    #[inline]
258    fn try_from(c: char) -> Result<Char8> {
259        Char8::try_from_char(c)
260    }
261}
262impl TryFrom<char> for Char16 {
263    type Error = TextosError;
264    #[inline]
265    fn try_from(c: char) -> Result<Char16> {
266        Char16::try_from_char(c)
267    }
268}
269impl From<char> for Char24 {
270    #[inline]
271    fn from(c: char) -> Char24 {
272        Char24::from_char(c)
273    }
274}
275impl From<char> for Char32 {
276    #[inline]
277    fn from(c: char) -> Char32 {
278        Char32::from_char(c)
279    }
280}