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 `extracted/DerivedCombiningClass.txt` file.
11///
12/// This file gives the derived values of the Canonical_Combining_Class
13/// property.
14#[derive(Clone, Debug, Default, Eq, PartialEq)]
15pub struct DerivedCombiningClass {
16 /// The codepoint or codepoint range for this entry.
17 pub codepoints: Codepoints,
18 /// The derived Canonical_Combining_Class of the codepoints in this entry.
19 pub combining_class: String,
20}
21
22impl UcdFile for DerivedCombiningClass {
23 fn relative_file_path() -> &'static Path {
24 Path::new("extracted/DerivedCombiningClass.txt")
25 }
26}
27
28impl UcdFileByCodepoint for DerivedCombiningClass {
29 fn codepoints(&self) -> CodepointIter {
30 self.codepoints.into_iter()
31 }
32}
33
34impl FromStr for DerivedCombiningClass {
35 type Err = Error;
36
37 fn from_str(line: &str) -> Result<DerivedCombiningClass, Error> {
38 let (codepoints: Codepoints, combining_class: &str) = parse_codepoint_association(line)?;
39 Ok(DerivedCombiningClass {
40 codepoints,
41 combining_class: combining_class.to_string(),
42 })
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::DerivedCombiningClass;
49
50 #[test]
51 fn parse_single() {
52 let line = "0020 ; 0 # Zs SPACE\n";
53 let row: DerivedCombiningClass = line.parse().unwrap();
54 assert_eq!(row.codepoints, 0x0020);
55 assert_eq!(row.combining_class, "0");
56 }
57
58 #[test]
59 fn parse_range() {
60 let line = "1DD1..1DF5 ; 230 # Mn [37] COMBINING UR ABOVE..COMBINING UP TACK ABOVE\n";
61 let row: DerivedCombiningClass = line.parse().unwrap();
62 assert_eq!(row.codepoints, (0x1DD1, 0x1DF5));
63 assert_eq!(row.combining_class, "230");
64 }
65}
66