1 // Copyright 2017 The Servo Project Developers. See the
2 // COPYRIGHT file at the top-level directory of this distribution.
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.
10 //! Bidi Embedding Level
12 //! See [`Level`](struct.Level.html) for more details.
14 //! <http://www.unicode.org/reports/tr9/#BD2>
16 use std
::convert
::{From, Into}
;
18 use super::char_data
::BidiClass
;
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.
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`.
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))]
34 pub const LTR_LEVEL
: Level
= Level(0);
35 pub const RTL_LEVEL
: Level
= Level(1);
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;
43 /// Errors that can occur on Level creation or mutation
44 #[derive(Debug, PartialEq)]
46 /// Out-of-range (invalid) embedding level number.
51 /// New LTR level with smallest number value (0).
53 pub fn ltr() -> Level
{
57 /// New RTL level with smallest number value (1).
59 pub fn rtl() -> Level
{
63 /// Maximum depth of the directional status stack during implicit resolutions.
64 pub fn max_implicit_depth() -> u8 {
68 /// Maximum depth of the directional status stack during explicit resolutions.
69 pub fn max_explicit_depth() -> u8 {
75 /// Create new level, fail if number is larger than `max_depth + 1`.
77 pub fn new(number
: u8) -> Result
<Level
, Error
> {
78 if number
<= MAX_IMPLICIT_DEPTH
{
81 Err(Error
::OutOfRangeNumber
)
85 /// Create new level, fail if number is larger than `max_depth`.
87 pub fn new_explicit(number
: u8) -> Result
<Level
, Error
> {
88 if number
<= MAX_EXPLICIT_DEPTH
{
91 Err(Error
::OutOfRangeNumber
)
99 pub fn number(&self) -> u8 {
103 /// If this level is left-to-right.
105 pub fn is_ltr(&self) -> bool
{
109 /// If this level is right-to-left.
111 pub fn is_rtl(&self) -> bool
{
117 /// Raise level by `amount`, fail if number is larger than `max_depth + 1`.
119 pub fn raise(&mut self, amount
: u8) -> Result
<(), Error
> {
120 match self.0.checked_add(amount
) {
122 if number
<= MAX_IMPLICIT_DEPTH
{
126 Err(Error
::OutOfRangeNumber
)
129 None
=> Err(Error
::OutOfRangeNumber
),
133 /// Raise level by `amount`, fail if number is larger than `max_depth`.
135 pub fn raise_explicit(&mut self, amount
: u8) -> Result
<(), Error
> {
136 match self.0.checked_add(amount
) {
138 if number
<= MAX_EXPLICIT_DEPTH
{
142 Err(Error
::OutOfRangeNumber
)
145 None
=> Err(Error
::OutOfRangeNumber
),
149 /// Lower level by `amount`, fail if number goes below zero.
151 pub fn lower(&mut self, amount
: u8) -> Result
<(), Error
> {
152 match self.0.checked_sub(amount
) {
157 None
=> Err(Error
::OutOfRangeNumber
),
163 /// The next LTR (even) level greater than this, or fail if number is larger than `max_depth`.
165 pub fn new_explicit_next_ltr(&self) -> Result
<Level
, Error
> {
166 Level
::new_explicit((self.0 + 2) & !1)
169 /// The next RTL (odd) level greater than this, or fail if number is larger than `max_depth`.
171 pub fn new_explicit_next_rtl(&self) -> Result
<Level
, Error
> {
172 Level
::new_explicit((self.0 + 1) | 1)
175 /// The lowest RTL (odd) level greater than or equal to this, or fail if number is larger than
178 pub fn new_lowest_ge_rtl(&self) -> Result
<Level
, Error
> {
179 Level
::new(self.0 | 1)
182 /// Generate a character type based on a level (as specified in steps X10 and N2).
184 pub fn bidi_class(&self) -> BidiClass
{
192 pub fn vec(v
: &[u8]) -> Vec
<Level
> {
193 v
.iter().map(|&x
| x
.into()).collect()
197 /// If levels has any RTL (odd) level
199 /// This information is usually used to skip re-ordering of text when no RTL level is present
201 pub fn has_rtl(levels
: &[Level
]) -> bool
{
202 levels
.iter().any(|&lvl
| lvl
.is_rtl())
205 impl Into
<u8> for Level
{
206 /// Convert to the level number
208 fn into(self) -> u8 {
213 impl From
<u8> for Level
{
214 /// Create level by number
216 fn from(number
: u8) -> Level
{
217 Level
::new(number
).expect("Level number error")
221 /// Used for matching levels in conformance tests
222 impl<'a
> PartialEq
<&'a
str> for Level
{
224 fn eq(&self, s
: &&'a
str) -> bool
{
225 *s
== "x" || *s
== self.0.to_string()
229 /// Used for matching levels in conformance tests
230 impl<'a
> PartialEq
<String
> for Level
{
232 fn eq(&self, s
: &String
) -> bool
{
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
));
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
));
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);
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);
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);
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);
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);
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);
330 let level
= Level
::rtl();
331 assert_eq
!(1u8, level
.into());
337 Level
::vec(&[0, 1, 125]),
338 vec
![Level(0), Level(1), Level(125)]
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"]);
349 fn test_string_eq() {
351 Level
::vec(&[0, 1, 4, 125]),
352 vec
!["0".to_string(), "1".to_string(), "x".to_string(), "125".to_string()]
357 #[cfg(all(feature = "serde", test))]
359 use serde_test
::{Token, assert_tokens}
;
366 &[Token
::NewtypeStruct { name: "Level" }
, Token
::U8(0)],
370 &[Token
::NewtypeStruct { name: "Level" }
, Token
::U8(1)],
376 let level
= Level
::new(42).unwrap();
379 &[Token
::NewtypeStruct { name: "Level" }
, Token
::U8(42)],