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