1use std::convert::{From, Into};
19use std::fmt;
20
21use unic_ucd_bidi::BidiClass;
22
23#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
34#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
35pub struct Level(u8);
36
37pub const LTR_LEVEL: Level = Level(0);
39
40pub const RTL_LEVEL: Level = Level(1);
42
43const MAX_DEPTH: u8 = 125;
44pub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;
46pub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;
48
49#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
51pub enum Error {
52 OutOfRangeNumber,
54}
55
56impl Level {
57 #[inline]
59 pub fn ltr() -> Level {
60 LTR_LEVEL
61 }
62
63 #[inline]
65 pub fn rtl() -> Level {
66 RTL_LEVEL
67 }
68
69 pub fn max_implicit_depth() -> u8 {
71 MAX_IMPLICIT_DEPTH
72 }
73
74 pub fn max_explicit_depth() -> u8 {
76 MAX_EXPLICIT_DEPTH
77 }
78
79 #[inline]
83 pub fn new(number: u8) -> Result<Level, Error> {
84 if number <= MAX_IMPLICIT_DEPTH {
85 Ok(Level(number))
86 } else {
87 Err(Error::OutOfRangeNumber)
88 }
89 }
90
91 #[inline]
93 pub fn new_explicit(number: u8) -> Result<Level, Error> {
94 if number <= MAX_EXPLICIT_DEPTH {
95 Ok(Level(number))
96 } else {
97 Err(Error::OutOfRangeNumber)
98 }
99 }
100
101 #[inline]
105 pub fn number(&self) -> u8 {
106 self.0
107 }
108
109 #[inline]
111 pub fn is_ltr(&self) -> bool {
112 self.0 % 2 == 0
113 }
114
115 #[inline]
117 pub fn is_rtl(&self) -> bool {
118 self.0 % 2 == 1
119 }
120
121 #[inline]
125 pub fn raise(&mut self, amount: u8) -> Result<(), Error> {
126 match self.0.checked_add(amount) {
127 Some(number) => {
128 if number <= MAX_IMPLICIT_DEPTH {
129 self.0 = number;
130 Ok(())
131 } else {
132 Err(Error::OutOfRangeNumber)
133 }
134 }
135 None => Err(Error::OutOfRangeNumber),
136 }
137 }
138
139 #[inline]
141 pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {
142 match self.0.checked_add(amount) {
143 Some(number) => {
144 if number <= MAX_EXPLICIT_DEPTH {
145 self.0 = number;
146 Ok(())
147 } else {
148 Err(Error::OutOfRangeNumber)
149 }
150 }
151 None => Err(Error::OutOfRangeNumber),
152 }
153 }
154
155 #[inline]
157 pub fn lower(&mut self, amount: u8) -> Result<(), Error> {
158 match self.0.checked_sub(amount) {
159 Some(number) => {
160 self.0 = number;
161 Ok(())
162 }
163 None => Err(Error::OutOfRangeNumber),
164 }
165 }
166
167 #[inline]
171 pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {
172 Level::new_explicit((self.0 + 2) & !1)
173 }
174
175 #[inline]
177 pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {
178 Level::new_explicit((self.0 + 1) | 1)
179 }
180
181 #[inline]
184 pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {
185 Level::new(self.0 | 1)
186 }
187
188 #[inline]
190 pub fn bidi_class(&self) -> BidiClass {
191 if self.is_rtl() {
192 BidiClass::RightToLeft
193 } else {
194 BidiClass::LeftToRight
195 }
196 }
197
198 pub fn vec(v: &[u8]) -> Vec<Level> {
200 v.iter().map(|&x| x.into()).collect()
201 }
202}
203
204impl fmt::Display for Level {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 write!(f, "{}", self.0)
207 }
208}
209
210#[inline]
214pub fn has_rtl(levels: &[Level]) -> bool {
215 levels.iter().any(|&lvl| lvl.is_rtl())
216}
217
218impl Into<u8> for Level {
219 #[inline]
221 fn into(self) -> u8 {
222 self.number()
223 }
224}
225
226impl From<u8> for Level {
227 #[inline]
229 fn from(number: u8) -> Level {
230 Level::new(number).expect("Level number error")
231 }
232}
233
234impl<'a> PartialEq<&'a str> for Level {
236 #[inline]
237 fn eq(&self, s: &&'a str) -> bool {
238 *s == "x" || *s == self.0.to_string()
239 }
240}
241
242impl<'a> PartialEq<String> for Level {
244 #[inline]
245 fn eq(&self, s: &String) -> bool {
246 self == &s.as_str()
247 }
248}
249
250#[cfg(test)]
251mod tests {
252 use super::*;
253
254 #[test]
255 fn test_new() {
256 assert_eq!(Level::new(0), Ok(Level(0)));
257 assert_eq!(Level::new(1), Ok(Level(1)));
258 assert_eq!(Level::new(10), Ok(Level(10)));
259 assert_eq!(Level::new(125), Ok(Level(125)));
260 assert_eq!(Level::new(126), Ok(Level(126)));
261 assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));
262 assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));
263 }
264
265 #[test]
266 fn test_new_explicit() {
267 assert_eq!(Level::new_explicit(0), Ok(Level(0)));
268 assert_eq!(Level::new_explicit(1), Ok(Level(1)));
269 assert_eq!(Level::new_explicit(10), Ok(Level(10)));
270 assert_eq!(Level::new_explicit(125), Ok(Level(125)));
271 assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));
272 assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));
273 }
274
275 #[test]
276 fn test_is_ltr() {
277 assert_eq!(Level(0).is_ltr(), true);
278 assert_eq!(Level(1).is_ltr(), false);
279 assert_eq!(Level(10).is_ltr(), true);
280 assert_eq!(Level(11).is_ltr(), false);
281 assert_eq!(Level(124).is_ltr(), true);
282 assert_eq!(Level(125).is_ltr(), false);
283 }
284
285 #[test]
286 fn test_is_rtl() {
287 assert_eq!(Level(0).is_rtl(), false);
288 assert_eq!(Level(1).is_rtl(), true);
289 assert_eq!(Level(10).is_rtl(), false);
290 assert_eq!(Level(11).is_rtl(), true);
291 assert_eq!(Level(124).is_rtl(), false);
292 assert_eq!(Level(125).is_rtl(), true);
293 }
294
295 #[test]
296 fn test_raise() {
297 let mut level = Level::ltr();
298 assert_eq!(level.number(), 0);
299 assert!(level.raise(100).is_ok());
300 assert_eq!(level.number(), 100);
301 assert!(level.raise(26).is_ok());
302 assert_eq!(level.number(), 126);
303 assert!(level.raise(1).is_err()); assert!(level.raise(250).is_err()); assert_eq!(level.number(), 126);
306 }
307
308 #[test]
309 fn test_raise_explicit() {
310 let mut level = Level::ltr();
311 assert_eq!(level.number(), 0);
312 assert!(level.raise_explicit(100).is_ok());
313 assert_eq!(level.number(), 100);
314 assert!(level.raise_explicit(25).is_ok());
315 assert_eq!(level.number(), 125);
316 assert!(level.raise_explicit(1).is_err()); assert!(level.raise_explicit(250).is_err()); assert_eq!(level.number(), 125);
319 }
320
321 #[test]
322 fn test_lower() {
323 let mut level = Level::rtl();
324 assert_eq!(level.number(), 1);
325 assert!(level.lower(1).is_ok());
326 assert_eq!(level.number(), 0);
327 assert!(level.lower(1).is_err()); assert!(level.lower(250).is_err()); assert_eq!(level.number(), 0);
330 }
331
332 #[test]
333 fn test_has_rtl() {
334 assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);
335 assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);
336 assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);
337 assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);
338 assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);
339 }
340
341 #[test]
342 fn test_into() {
343 let level = Level::rtl();
344 assert_eq!(1u8, level.into());
345 }
346
347 #[test]
348 fn test_vec() {
349 assert_eq!(
350 Level::vec(&[0, 1, 125]),
351 vec![Level(0), Level(1), Level(125)]
352 );
353 }
354
355 #[test]
356 fn test_str_eq() {
357 assert_eq!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "x", "125"]);
358 assert_ne!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "5", "125"]);
359 }
360
361 #[test]
362 fn test_string_eq() {
363 assert_eq!(
364 Level::vec(&[0, 1, 4, 125]),
365 vec![
366 "0".to_string(),
367 "1".to_string(),
368 "x".to_string(),
369 "125".to_string(),
370 ]
371 );
372 }
373}
374
375#[cfg(all(feature = "serde", test))]
376mod serde_tests {
377 use super::*;
378 use serde_test::{assert_tokens, Token};
379
380 #[test]
381 fn test_statics() {
382 assert_tokens(
383 &Level::ltr(),
384 &[Token::NewtypeStruct { name: "Level" }, Token::U8(0)],
385 );
386 assert_tokens(
387 &Level::rtl(),
388 &[Token::NewtypeStruct { name: "Level" }, Token::U8(1)],
389 );
390 }
391
392 #[test]
393 fn test_new() {
394 let level = Level::new(42).unwrap();
395 assert_tokens(
396 &level,
397 &[Token::NewtypeStruct { name: "Level" }, Token::U8(42)],
398 );
399 }
400}