1 /// The type of a property name table.
2 ///
3 /// A property name table is a sequence of sorted tuples, where the first
4 /// value in each tuple is a normalized property name and the second value of
5 /// each tuple is the corresponding canonical property name.
6 pub type PropertyTable = &'static [(&'static str, &'static str)];
7 
8 /// Find the canonical property name for the given normalized property name.
9 ///
10 /// If no such property exists, then `None` is returned.
11 ///
12 /// The normalized property name must have been normalized according to
13 /// UAX44 LM3, which can be done using `symbolic_name_normalize`.
canonical_property_name( property_table: PropertyTable, normalized_property_name: &str, ) -> Option<&'static str>14 pub fn canonical_property_name(
15     property_table: PropertyTable,
16     normalized_property_name: &str,
17 ) -> Option<&'static str> {
18     property_table
19         .binary_search_by_key(&normalized_property_name, |&(n, _)| n)
20         .ok()
21         .map(|i| property_table[i].1)
22 }
23 
24 /// Type of a property value table.
25 ///
26 /// A property value table maps property names to a mapping of property values,
27 /// where the mapping of property values is represented by a sequence of
28 /// tuples. The first element of each tuple is a normalized property value
29 /// while the second element of each tuple is the corresponding canonical
30 /// property value.
31 ///
32 /// Note that a property value table only includes values for properties that
33 /// are catalogs, enumerations or binary properties. Properties that have
34 /// string values (such as case or decomposition mappings), numeric values
35 /// or are miscellaneous are not represented in this table.
36 pub type PropertyValueTable = &'static [(&'static str, PropertyValues)];
37 
38 /// A mapping of property values for a specific property.
39 ///
40 /// The first element of each tuple is a normalized property value while the
41 /// second element of each tuple is the corresponding canonical property
42 /// value.
43 pub type PropertyValues = &'static [(&'static str, &'static str)];
44 
45 /// Find the set of possible property values for a given property.
46 ///
47 /// The set returned is a mapping expressed as a sorted list of tuples.
48 /// The first element of each tuple is a normalized property value while the
49 /// second element of each tuple is the corresponding canonical property
50 /// value.
51 ///
52 /// If no such property exists, then `None` is returned.
53 ///
54 /// The given property name must be in its canonical form, which can be
55 /// found using `canonical_property_name`.
property_values( property_value_table: PropertyValueTable, canonical_property_name: &str, ) -> Option<PropertyValues>56 pub fn property_values(
57     property_value_table: PropertyValueTable,
58     canonical_property_name: &str,
59 ) -> Option<PropertyValues> {
60     property_value_table
61         .binary_search_by_key(&canonical_property_name, |&(n, _)| n)
62         .ok()
63         .map(|i| property_value_table[i].1)
64 }
65 
66 /// Find the canonical property value for the given normalized property
67 /// value.
68 ///
69 /// The given property values should correspond to the values for the property
70 /// under question, which can be found using `property_values`.
71 ///
72 /// If no such property value exists, then `None` is returned.
73 ///
74 /// The normalized property value must have been normalized according to
75 /// UAX44 LM3, which can be done using `symbolic_name_normalize`.
canonical_property_value( property_values: PropertyValues, normalized_property_value: &str, ) -> Option<&'static str>76 pub fn canonical_property_value(
77     property_values: PropertyValues,
78     normalized_property_value: &str,
79 ) -> Option<&'static str> {
80     // This is cute. The types line up, so why not?
81     canonical_property_name(property_values, normalized_property_value)
82 }
83 
84 
85 #[cfg(test)]
86 mod tests {
87     use unicode_tables::property_names::PROPERTY_NAMES;
88     use unicode_tables::property_values::PROPERTY_VALUES;
89 
90     use super::{
91         canonical_property_name, property_values, canonical_property_value,
92     };
93 
94     #[test]
canonical_property_name_1()95     fn canonical_property_name_1() {
96         assert_eq!(
97             canonical_property_name(PROPERTY_NAMES, "gc"),
98             Some("General_Category"));
99         assert_eq!(
100             canonical_property_name(PROPERTY_NAMES, "generalcategory"),
101             Some("General_Category"));
102         assert_eq!(
103             canonical_property_name(PROPERTY_NAMES, "g c"),
104             None);
105     }
106 
107     #[test]
property_values_1()108     fn property_values_1() {
109         assert_eq!(
110             property_values(PROPERTY_VALUES, "White_Space"),
111             Some(&[
112                 ("f", "No"), ("false", "No"), ("n", "No"), ("no", "No"),
113                 ("t", "Yes"), ("true", "Yes"), ("y", "Yes"), ("yes", "Yes"),
114             ][..]));
115     }
116 
117     #[test]
canonical_property_value_1()118     fn canonical_property_value_1() {
119         let values = property_values(PROPERTY_VALUES, "White_Space").unwrap();
120         assert_eq!(canonical_property_value(values, "false"), Some("No"));
121         assert_eq!(canonical_property_value(values, "t"), Some("Yes"));
122         assert_eq!(canonical_property_value(values, "F"), None);
123     }
124 }
125