1use std::path::Path;
2use std::str::FromStr;
3
4use crate::common::{
5 parse_codepoint_association, CodepointIter, Codepoints, UcdFile,
6 UcdFileByCodepoint,
7};
8use crate::error::Error;
9
10/// A single row in the `PropList.txt` file.
11///
12/// The `PropList.txt` file is the source of truth on several Unicode
13/// properties.
14#[derive(Clone, Debug, Default, Eq, PartialEq)]
15pub struct Property {
16 /// The codepoint or codepoint range for this entry.
17 pub codepoints: Codepoints,
18 /// The property name assigned to the codepoints in this entry.
19 pub property: String,
20}
21
22impl UcdFile for Property {
23 fn relative_file_path() -> &'static Path {
24 Path::new("PropList.txt")
25 }
26}
27
28impl UcdFileByCodepoint for Property {
29 fn codepoints(&self) -> CodepointIter {
30 self.codepoints.into_iter()
31 }
32}
33
34impl FromStr for Property {
35 type Err = Error;
36
37 fn from_str(line: &str) -> Result<Property, Error> {
38 let (codepoints: Codepoints, property: &str) = parse_codepoint_association(line)?;
39 Ok(Property { codepoints, property: property.to_string() })
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::Property;
46
47 #[test]
48 fn parse_single() {
49 let line =
50 "061C ; Bidi_Control # Cf ARABIC LETTER MARK\n";
51 let row: Property = line.parse().unwrap();
52 assert_eq!(row.codepoints, 0x061C);
53 assert_eq!(row.property, "Bidi_Control");
54 }
55
56 #[test]
57 fn parse_range() {
58 let line = "0009..000D ; White_Space # Cc [5] <control-0009>..<control-000D>\n";
59 let row: Property = line.parse().unwrap();
60 assert_eq!(row.codepoints, (0x0009, 0x000D));
61 assert_eq!(row.property, "White_Space");
62 }
63}
64