unicode_bidi/char_data/
mod.rs

1// Copyright 2015 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//! Accessor for `Bidi_Class` property from Unicode Character Database (UCD)
11
12mod tables;
13
14pub use self::tables::{BidiClass, UNICODE_VERSION};
15
16use std::cmp::Ordering::{Equal, Less, Greater};
17use std::char;
18
19use self::tables::bidi_class_table;
20use BidiClass::*;
21
22/// Find the `BidiClass` of a single char.
23pub fn bidi_class(c: char) -> BidiClass {
24    bsearch_range_value_table(c, bidi_class_table)
25}
26
27pub fn is_rtl(bidi_class: BidiClass) -> bool {
28    match bidi_class {
29        RLE | RLO | RLI => true,
30        _ => false,
31    }
32}
33
34fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
35    match r.binary_search_by(|&(lo, hi, _)| if lo <= c && c <= hi {
36        Equal
37    } else if hi < c {
38        Less
39    } else {
40        Greater
41    }) {
42        Ok(idx) => {
43            let (_, _, cat) = r[idx];
44            cat
45        }
46        // UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
47        // for Bidi_Class have the value Left_To_Right (L)."
48        Err(_) => L,
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn test_ascii() {
58        assert_eq!(bidi_class('\u{0000}'), BN);
59        assert_eq!(bidi_class('\u{0040}'), ON);
60        assert_eq!(bidi_class('\u{0041}'), L);
61        assert_eq!(bidi_class('\u{0062}'), L);
62        assert_eq!(bidi_class('\u{007F}'), BN);
63    }
64
65    #[test]
66    fn test_bmp() {
67        // Hebrew
68        assert_eq!(bidi_class('\u{0590}'), R);
69        assert_eq!(bidi_class('\u{05D0}'), R);
70        assert_eq!(bidi_class('\u{05D1}'), R);
71        assert_eq!(bidi_class('\u{05FF}'), R);
72
73        // Arabic
74        assert_eq!(bidi_class('\u{0600}'), AN);
75        assert_eq!(bidi_class('\u{0627}'), AL);
76        assert_eq!(bidi_class('\u{07BF}'), AL);
77
78        // Default R + Arabic Extras
79        assert_eq!(bidi_class('\u{07C0}'), R);
80        assert_eq!(bidi_class('\u{085F}'), R);
81        assert_eq!(bidi_class('\u{0860}'), AL);
82        assert_eq!(bidi_class('\u{0870}'), R);
83        assert_eq!(bidi_class('\u{089F}'), R);
84        assert_eq!(bidi_class('\u{08A0}'), AL);
85        assert_eq!(bidi_class('\u{089F}'), R);
86        assert_eq!(bidi_class('\u{08FF}'), NSM);
87
88        // Default ET
89        assert_eq!(bidi_class('\u{20A0}'), ET);
90        assert_eq!(bidi_class('\u{20CF}'), ET);
91
92        // Arabic Presentation Forms
93        assert_eq!(bidi_class('\u{FB1D}'), R);
94        assert_eq!(bidi_class('\u{FB4F}'), R);
95        assert_eq!(bidi_class('\u{FB50}'), AL);
96        assert_eq!(bidi_class('\u{FDCF}'), AL);
97        assert_eq!(bidi_class('\u{FDF0}'), AL);
98        assert_eq!(bidi_class('\u{FDFF}'), AL);
99        assert_eq!(bidi_class('\u{FE70}'), AL);
100        assert_eq!(bidi_class('\u{FEFE}'), AL);
101        assert_eq!(bidi_class('\u{FEFF}'), BN);
102
103        // noncharacters
104        assert_eq!(bidi_class('\u{FDD0}'), L);
105        assert_eq!(bidi_class('\u{FDD1}'), L);
106        assert_eq!(bidi_class('\u{FDEE}'), L);
107        assert_eq!(bidi_class('\u{FDEF}'), L);
108        assert_eq!(bidi_class('\u{FFFE}'), L);
109        assert_eq!(bidi_class('\u{FFFF}'), L);
110    }
111
112    #[test]
113    fn test_smp() {
114        // Default AL + R
115        assert_eq!(bidi_class('\u{10800}'), R);
116        assert_eq!(bidi_class('\u{10FFF}'), R);
117        assert_eq!(bidi_class('\u{1E800}'), R);
118        assert_eq!(bidi_class('\u{1EDFF}'), R);
119        assert_eq!(bidi_class('\u{1EE00}'), AL);
120        assert_eq!(bidi_class('\u{1EEFF}'), AL);
121        assert_eq!(bidi_class('\u{1EF00}'), R);
122        assert_eq!(bidi_class('\u{1EFFF}'), R);
123    }
124
125    #[test]
126    fn test_unassigned_planes() {
127        assert_eq!(bidi_class('\u{30000}'), L);
128        assert_eq!(bidi_class('\u{40000}'), L);
129        assert_eq!(bidi_class('\u{50000}'), L);
130        assert_eq!(bidi_class('\u{60000}'), L);
131        assert_eq!(bidi_class('\u{70000}'), L);
132        assert_eq!(bidi_class('\u{80000}'), L);
133        assert_eq!(bidi_class('\u{90000}'), L);
134        assert_eq!(bidi_class('\u{a0000}'), L);
135    }
136}