ucd_parse/
east_asian_width.rs

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 `EastAsianWidth.txt` file, describing the value of the
12/// `East_Asian_Width` property.
13///
14/// Note: All code points, assigned or unassigned, that are not listed in
15/// EastAsianWidth.txt file are given the value "N".
16#[derive(Clone, Debug, Default, Eq, PartialEq)]
17pub struct EastAsianWidth {
18    /// The codepoint or codepoint range for this entry.
19    pub codepoints: Codepoints,
20    /// One of "A", "F", "H", "N", "Na", "W".
21    pub width: String,
22}
23
24impl UcdFile for EastAsianWidth {
25    fn relative_file_path() -> &'static Path {
26        Path::new("EastAsianWidth.txt")
27    }
28}
29
30impl UcdFileByCodepoint for EastAsianWidth {
31    fn codepoints(&self) -> CodepointIter {
32        self.codepoints.into_iter()
33    }
34}
35
36impl std::str::FromStr for EastAsianWidth {
37    type Err = Error;
38
39    fn from_str(line: &str) -> Result<EastAsianWidth, Error> {
40        let (codepoints, width) = parse_codepoint_association(line)?;
41        Ok(EastAsianWidth { codepoints, width: width.to_string() })
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::EastAsianWidth;
48
49    #[test]
50    fn parse_single() {
51        let line = "27E7;Na          # Pe         MATHEMATICAL RIGHT WHITE SQUARE BRACKET\n";
52        let row: EastAsianWidth = line.parse().unwrap();
53        assert_eq!(row.codepoints, 0x27E7);
54        assert_eq!(row.width, "Na");
55    }
56
57    #[test]
58    fn parse_range() {
59        let line = "1F57B..1F594;N   # So    [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND\n";
60        let row: EastAsianWidth = line.parse().unwrap();
61        assert_eq!(row.codepoints, (0x1F57B, 0x1F594));
62        assert_eq!(row.width, "N");
63    }
64}