1 // Copyright 2017 The Servo Project Developers. See the
2 // COPYRIGHT file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 //! Bidi Embedding Level
11 //!
12 //! See [`Level`](struct.Level.html) for more details.
13 //!
14 //! <http://www.unicode.org/reports/tr9/#BD2>
15 
16 use std::convert::{From, Into};
17 
18 use super::char_data::BidiClass;
19 
20 /// Embedding Level
21 ///
22 /// Embedding Levels are numbers between 0 and 126 (inclusive), where even values denote a
23 /// left-to-right (LTR) direction and odd values a right-to-left (RTL) direction.
24 ///
25 /// This struct maintains a *valid* status for level numbers, meaning that creating a new level, or
26 /// mutating an existing level, with the value smaller than `0` (before conversion to `u8`) or
27 /// larger than 125 results in an `Error`.
28 ///
29 /// <http://www.unicode.org/reports/tr9/#BD2>
30 #[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
31 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
32 pub struct Level(u8);
33 
34 pub const LTR_LEVEL: Level = Level(0);
35 pub const RTL_LEVEL: Level = Level(1);
36 
37 const MAX_DEPTH: u8 = 125;
38 /// During explicit level resolution, embedding level can go as high as `max_depth`.
39 pub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;
40 /// During implicit level resolution, embedding level can go as high as `max_depth + 1`.
41 pub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;
42 
43 /// Errors that can occur on Level creation or mutation
44 #[derive(Debug, PartialEq)]
45 pub enum Error {
46     /// Out-of-range (invalid) embedding level number.
47     OutOfRangeNumber,
48 }
49 
50 impl Level {
51     /// New LTR level with smallest number value (0).
52     #[inline]
ltr() -> Level53     pub fn ltr() -> Level {
54         LTR_LEVEL
55     }
56 
57     /// New RTL level with smallest number value (1).
58     #[inline]
rtl() -> Level59     pub fn rtl() -> Level {
60         RTL_LEVEL
61     }
62 
63     /// Maximum depth of the directional status stack during implicit resolutions.
max_implicit_depth() -> u864     pub fn max_implicit_depth() -> u8 {
65         MAX_IMPLICIT_DEPTH
66     }
67 
68     /// Maximum depth of the directional status stack during explicit resolutions.
max_explicit_depth() -> u869     pub fn max_explicit_depth() -> u8 {
70         MAX_EXPLICIT_DEPTH
71     }
72 
73     // == Inquiries ==
74 
75     /// Create new level, fail if number is larger than `max_depth + 1`.
76     #[inline]
new(number: u8) -> Result<Level, Error>77     pub fn new(number: u8) -> Result<Level, Error> {
78         if number <= MAX_IMPLICIT_DEPTH {
79             Ok(Level(number))
80         } else {
81             Err(Error::OutOfRangeNumber)
82         }
83     }
84 
85     /// Create new level, fail if number is larger than `max_depth`.
86     #[inline]
new_explicit(number: u8) -> Result<Level, Error>87     pub fn new_explicit(number: u8) -> Result<Level, Error> {
88         if number <= MAX_EXPLICIT_DEPTH {
89             Ok(Level(number))
90         } else {
91             Err(Error::OutOfRangeNumber)
92         }
93     }
94 
95     // == Inquiries ==
96 
97     /// The level number.
98     #[inline]
number(&self) -> u899     pub fn number(&self) -> u8 {
100         self.0
101     }
102 
103     /// If this level is left-to-right.
104     #[inline]
is_ltr(&self) -> bool105     pub fn is_ltr(&self) -> bool {
106         self.0 % 2 == 0
107     }
108 
109     /// If this level is right-to-left.
110     #[inline]
is_rtl(&self) -> bool111     pub fn is_rtl(&self) -> bool {
112         self.0 % 2 == 1
113     }
114 
115     // == Mutators ==
116 
117     /// Raise level by `amount`, fail if number is larger than `max_depth + 1`.
118     #[inline]
raise(&mut self, amount: u8) -> Result<(), Error>119     pub fn raise(&mut self, amount: u8) -> Result<(), Error> {
120         match self.0.checked_add(amount) {
121             Some(number) => {
122                 if number <= MAX_IMPLICIT_DEPTH {
123                     self.0 = number;
124                     Ok(())
125                 } else {
126                     Err(Error::OutOfRangeNumber)
127                 }
128             }
129             None => Err(Error::OutOfRangeNumber),
130         }
131     }
132 
133     /// Raise level by `amount`, fail if number is larger than `max_depth`.
134     #[inline]
raise_explicit(&mut self, amount: u8) -> Result<(), Error>135     pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {
136         match self.0.checked_add(amount) {
137             Some(number) => {
138                 if number <= MAX_EXPLICIT_DEPTH {
139                     self.0 = number;
140                     Ok(())
141                 } else {
142                     Err(Error::OutOfRangeNumber)
143                 }
144             }
145             None => Err(Error::OutOfRangeNumber),
146         }
147     }
148 
149     /// Lower level by `amount`, fail if number goes below zero.
150     #[inline]
lower(&mut self, amount: u8) -> Result<(), Error>151     pub fn lower(&mut self, amount: u8) -> Result<(), Error> {
152         match self.0.checked_sub(amount) {
153             Some(number) => {
154                 self.0 = number;
155                 Ok(())
156             }
157             None => Err(Error::OutOfRangeNumber),
158         }
159     }
160 
161     // == Helpers ==
162 
163     /// The next LTR (even) level greater than this, or fail if number is larger than `max_depth`.
164     #[inline]
new_explicit_next_ltr(&self) -> Result<Level, Error>165     pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {
166         Level::new_explicit((self.0 + 2) & !1)
167     }
168 
169     /// The next RTL (odd) level greater than this, or fail if number is larger than `max_depth`.
170     #[inline]
new_explicit_next_rtl(&self) -> Result<Level, Error>171     pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {
172         Level::new_explicit((self.0 + 1) | 1)
173     }
174 
175     /// The lowest RTL (odd) level greater than or equal to this, or fail if number is larger than
176     /// `max_depth + 1`.
177     #[inline]
new_lowest_ge_rtl(&self) -> Result<Level, Error>178     pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {
179         Level::new(self.0 | 1)
180     }
181 
182     /// Generate a character type based on a level (as specified in steps X10 and N2).
183     #[inline]
bidi_class(&self) -> BidiClass184     pub fn bidi_class(&self) -> BidiClass {
185         if self.is_rtl() {
186             BidiClass::R
187         } else {
188             BidiClass::L
189         }
190     }
191 
vec(v: &[u8]) -> Vec<Level>192     pub fn vec(v: &[u8]) -> Vec<Level> {
193         v.iter().map(|&x| x.into()).collect()
194     }
195 }
196 
197 /// If levels has any RTL (odd) level
198 ///
199 /// This information is usually used to skip re-ordering of text when no RTL level is present
200 #[inline]
has_rtl(levels: &[Level]) -> bool201 pub fn has_rtl(levels: &[Level]) -> bool {
202     levels.iter().any(|&lvl| lvl.is_rtl())
203 }
204 
205 impl Into<u8> for Level {
206     /// Convert to the level number
207     #[inline]
into(self) -> u8208     fn into(self) -> u8 {
209         self.number()
210     }
211 }
212 
213 impl From<u8> for Level {
214     /// Create level by number
215     #[inline]
from(number: u8) -> Level216     fn from(number: u8) -> Level {
217         Level::new(number).expect("Level number error")
218     }
219 }
220 
221 /// Used for matching levels in conformance tests
222 impl<'a> PartialEq<&'a str> for Level {
223     #[inline]
eq(&self, s: &&'a str) -> bool224     fn eq(&self, s: &&'a str) -> bool {
225         *s == "x" || *s == self.0.to_string()
226     }
227 }
228 
229 /// Used for matching levels in conformance tests
230 impl<'a> PartialEq<String> for Level {
231     #[inline]
eq(&self, s: &String) -> bool232     fn eq(&self, s: &String) -> bool {
233         self == &s.as_str()
234     }
235 }
236 
237 #[cfg(test)]
238 mod tests {
239     use super::*;
240 
241     #[test]
test_new()242     fn test_new() {
243         assert_eq!(Level::new(0), Ok(Level(0)));
244         assert_eq!(Level::new(1), Ok(Level(1)));
245         assert_eq!(Level::new(10), Ok(Level(10)));
246         assert_eq!(Level::new(125), Ok(Level(125)));
247         assert_eq!(Level::new(126), Ok(Level(126)));
248         assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));
249         assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));
250     }
251 
252     #[test]
test_new_explicit()253     fn test_new_explicit() {
254         assert_eq!(Level::new_explicit(0), Ok(Level(0)));
255         assert_eq!(Level::new_explicit(1), Ok(Level(1)));
256         assert_eq!(Level::new_explicit(10), Ok(Level(10)));
257         assert_eq!(Level::new_explicit(125), Ok(Level(125)));
258         assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));
259         assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));
260     }
261 
262     #[test]
test_is_ltr()263     fn test_is_ltr() {
264         assert_eq!(Level(0).is_ltr(), true);
265         assert_eq!(Level(1).is_ltr(), false);
266         assert_eq!(Level(10).is_ltr(), true);
267         assert_eq!(Level(11).is_ltr(), false);
268         assert_eq!(Level(124).is_ltr(), true);
269         assert_eq!(Level(125).is_ltr(), false);
270     }
271 
272     #[test]
test_is_rtl()273     fn test_is_rtl() {
274         assert_eq!(Level(0).is_rtl(), false);
275         assert_eq!(Level(1).is_rtl(), true);
276         assert_eq!(Level(10).is_rtl(), false);
277         assert_eq!(Level(11).is_rtl(), true);
278         assert_eq!(Level(124).is_rtl(), false);
279         assert_eq!(Level(125).is_rtl(), true);
280     }
281 
282     #[test]
test_raise()283     fn test_raise() {
284         let mut level = Level::ltr();
285         assert_eq!(level.number(), 0);
286         assert!(level.raise(100).is_ok());
287         assert_eq!(level.number(), 100);
288         assert!(level.raise(26).is_ok());
289         assert_eq!(level.number(), 126);
290         assert!(level.raise(1).is_err()); // invalid!
291         assert!(level.raise(250).is_err()); // overflow!
292         assert_eq!(level.number(), 126);
293     }
294 
295     #[test]
test_raise_explicit()296     fn test_raise_explicit() {
297         let mut level = Level::ltr();
298         assert_eq!(level.number(), 0);
299         assert!(level.raise_explicit(100).is_ok());
300         assert_eq!(level.number(), 100);
301         assert!(level.raise_explicit(25).is_ok());
302         assert_eq!(level.number(), 125);
303         assert!(level.raise_explicit(1).is_err()); // invalid!
304         assert!(level.raise_explicit(250).is_err()); // overflow!
305         assert_eq!(level.number(), 125);
306     }
307 
308     #[test]
test_lower()309     fn test_lower() {
310         let mut level = Level::rtl();
311         assert_eq!(level.number(), 1);
312         assert!(level.lower(1).is_ok());
313         assert_eq!(level.number(), 0);
314         assert!(level.lower(1).is_err()); // underflow!
315         assert!(level.lower(250).is_err()); // underflow!
316         assert_eq!(level.number(), 0);
317     }
318 
319     #[test]
test_has_rtl()320     fn test_has_rtl() {
321         assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);
322         assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);
323         assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);
324         assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);
325         assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);
326     }
327 
328     #[test]
test_into()329     fn test_into() {
330         let level = Level::rtl();
331         assert_eq!(1u8, level.into());
332     }
333 
334     #[test]
test_vec()335     fn test_vec() {
336         assert_eq!(
337             Level::vec(&[0, 1, 125]),
338             vec![Level(0), Level(1), Level(125)]
339         );
340     }
341 
342     #[test]
test_str_eq()343     fn test_str_eq() {
344         assert_eq!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "x", "125"]);
345         assert_ne!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "5", "125"]);
346     }
347 
348     #[test]
test_string_eq()349     fn test_string_eq() {
350         assert_eq!(
351             Level::vec(&[0, 1, 4, 125]),
352             vec!["0".to_string(), "1".to_string(), "x".to_string(), "125".to_string()]
353         );
354     }
355 }
356 
357 #[cfg(all(feature = "serde", test))]
358 mod serde_tests {
359     use serde_test::{Token, assert_tokens};
360     use super::*;
361 
362     #[test]
test_statics()363     fn test_statics() {
364         assert_tokens(
365             &Level::ltr(),
366             &[Token::NewtypeStruct { name: "Level" }, Token::U8(0)],
367         );
368         assert_tokens(
369             &Level::rtl(),
370             &[Token::NewtypeStruct { name: "Level" }, Token::U8(1)],
371         );
372     }
373 
374     #[test]
test_new()375     fn test_new() {
376         let level = Level::new(42).unwrap();
377         assert_tokens(
378             &level,
379             &[Token::NewtypeStruct { name: "Level" }, Token::U8(42)],
380         );
381     }
382 }
383