From c61ae95d42b7d85e266cd5f334621e1ce8c6a1ef Mon Sep 17 00:00:00 2001 From: Aris Merchant <22333129+inquisitivecrystal@users.noreply.github.com> Date: Wed, 30 Jun 2021 00:15:07 -0700 Subject: [PATCH] ucd-parse: add support for parsing files under 'extracted/' Closes #46 --- ucd-parse/src/extracted/derived_bidi_class.rs | 61 ++++++++++++ .../extracted/derived_binary_properties.rs | 66 +++++++++++++ .../src/extracted/derived_combining_class.rs | 65 +++++++++++++ .../extracted/derived_decomposition_type.rs | 66 +++++++++++++ .../src/extracted/derived_east_asian_width.rs | 66 +++++++++++++ .../src/extracted/derived_general_category.rs | 65 +++++++++++++ .../src/extracted/derived_joining_group.rs | 64 +++++++++++++ .../src/extracted/derived_joining_type.rs | 64 +++++++++++++ ucd-parse/src/extracted/derived_line_break.rs | 61 ++++++++++++ ucd-parse/src/extracted/derived_name.rs | 61 ++++++++++++ .../src/extracted/derived_numeric_type.rs | 65 +++++++++++++ .../src/extracted/derived_numeric_values.rs | 92 +++++++++++++++++++ ucd-parse/src/extracted/mod.rs | 30 ++++++ ucd-parse/src/lib.rs | 2 + 14 files changed, 828 insertions(+) create mode 100644 ucd-parse/src/extracted/derived_bidi_class.rs create mode 100644 ucd-parse/src/extracted/derived_binary_properties.rs create mode 100644 ucd-parse/src/extracted/derived_combining_class.rs create mode 100644 ucd-parse/src/extracted/derived_decomposition_type.rs create mode 100644 ucd-parse/src/extracted/derived_east_asian_width.rs create mode 100644 ucd-parse/src/extracted/derived_general_category.rs create mode 100644 ucd-parse/src/extracted/derived_joining_group.rs create mode 100644 ucd-parse/src/extracted/derived_joining_type.rs create mode 100644 ucd-parse/src/extracted/derived_line_break.rs create mode 100644 ucd-parse/src/extracted/derived_name.rs create mode 100644 ucd-parse/src/extracted/derived_numeric_type.rs create mode 100644 ucd-parse/src/extracted/derived_numeric_values.rs create mode 100644 ucd-parse/src/extracted/mod.rs diff --git a/ucd-parse/src/extracted/derived_bidi_class.rs b/ucd-parse/src/extracted/derived_bidi_class.rs new file mode 100644 index 0000000..da38824 --- /dev/null +++ b/ucd-parse/src/extracted/derived_bidi_class.rs @@ -0,0 +1,61 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedBidiClass.txt` file. +/// +/// This file gives the derived values of the Bidi_Class property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedBidiClass { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Bidi_Class of the codepoints in this entry. + pub bidi_class: String, +} + +impl UcdFile for DerivedBidiClass { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedBidiClass.txt") + } +} + +impl UcdFileByCodepoint for DerivedBidiClass { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedBidiClass { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, bidi_class) = parse_codepoint_association(line)?; + Ok(DerivedBidiClass { codepoints, bidi_class: bidi_class.to_string() }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedBidiClass; + + #[test] + fn parse_single() { + let line = "00B5 ; L # L& MICRO SIGN\n"; + let row: DerivedBidiClass = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x00B5); + assert_eq!(row.bidi_class, "L"); + } + + #[test] + fn parse_range() { + let line = "0030..0039 ; EN # Nd [10] DIGIT ZERO..DIGIT NINE\n"; + let row: DerivedBidiClass = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x0030, 0x0039)); + assert_eq!(row.bidi_class, "EN"); + } +} diff --git a/ucd-parse/src/extracted/derived_binary_properties.rs b/ucd-parse/src/extracted/derived_binary_properties.rs new file mode 100644 index 0000000..19ba8cf --- /dev/null +++ b/ucd-parse/src/extracted/derived_binary_properties.rs @@ -0,0 +1,66 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedBinaryProperties.txt` file. +/// +/// This file indicates whether a codepoint has the Bidi_Mirrored property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedBinaryProperties { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived property of the codepoints in this entry. Currently, + /// this is always the always the string "Bidi_Mirrored". + pub property: String, +} + +impl UcdFile for DerivedBinaryProperties { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedBinaryProperties.txt") + } +} + +impl UcdFileByCodepoint for DerivedBinaryProperties { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedBinaryProperties { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, property) = parse_codepoint_association(line)?; + Ok(DerivedBinaryProperties { + codepoints, + property: property.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedBinaryProperties; + + #[test] + fn parse_single() { + let line = + "0028 ; Bidi_Mirrored # Ps LEFT PARENTHESIS\n"; + let row: DerivedBinaryProperties = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0028); + assert_eq!(row.property, "Bidi_Mirrored"); + } + + #[test] + fn parse_range() { + let line = "2A3C..2A3E ; Bidi_Mirrored # Sm [3] INTERIOR PRODUCT..Z NOTATION RELATIONAL COMPOSITION\n"; + let row: DerivedBinaryProperties = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x2A3C, 0x2A3E)); + assert_eq!(row.property, "Bidi_Mirrored"); + } +} diff --git a/ucd-parse/src/extracted/derived_combining_class.rs b/ucd-parse/src/extracted/derived_combining_class.rs new file mode 100644 index 0000000..9a26036 --- /dev/null +++ b/ucd-parse/src/extracted/derived_combining_class.rs @@ -0,0 +1,65 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedCombiningClass.txt` file. +/// +/// This file gives the derived values of the Canonical_Combining_Class +/// property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedCombiningClass { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Canonical_Combining_Class of the codepoints in this entry. + pub combining_class: String, +} + +impl UcdFile for DerivedCombiningClass { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedCombiningClass.txt") + } +} + +impl UcdFileByCodepoint for DerivedCombiningClass { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedCombiningClass { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, combining_class) = parse_codepoint_association(line)?; + Ok(DerivedCombiningClass { + codepoints, + combining_class: combining_class.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedCombiningClass; + + #[test] + fn parse_single() { + let line = "0020 ; 0 # Zs SPACE\n"; + let row: DerivedCombiningClass = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0020); + assert_eq!(row.combining_class, "0"); + } + + #[test] + fn parse_range() { + let line = "1DD1..1DF5 ; 230 # Mn [37] COMBINING UR ABOVE..COMBINING UP TACK ABOVE\n"; + let row: DerivedCombiningClass = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x1DD1, 0x1DF5)); + assert_eq!(row.combining_class, "230"); + } +} diff --git a/ucd-parse/src/extracted/derived_decomposition_type.rs b/ucd-parse/src/extracted/derived_decomposition_type.rs new file mode 100644 index 0000000..b0b605a --- /dev/null +++ b/ucd-parse/src/extracted/derived_decomposition_type.rs @@ -0,0 +1,66 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedCombiningClass.txt` file. +/// +/// This file gives the derived values of the Decomposition_Type +/// property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedDecompositionType { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Decomposition_Type of the codepoints in this entry. + pub decomposition_type: String, +} + +impl UcdFile for DerivedDecompositionType { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedDecompositionType.txt") + } +} + +impl UcdFileByCodepoint for DerivedDecompositionType { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedDecompositionType { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, decomposition_type) = + parse_codepoint_association(line)?; + Ok(DerivedDecompositionType { + codepoints, + decomposition_type: decomposition_type.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedDecompositionType; + + #[test] + fn parse_single() { + let line = "00A0 ; Nobreak # Zs NO-BREAK SPACE\n"; + let row: DerivedDecompositionType = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x00A0); + assert_eq!(row.decomposition_type, "Nobreak"); + } + + #[test] + fn parse_range() { + let line = "3070..3071 ; Canonical # Lo [2] HIRAGANA LETTER BA..HIRAGANA LETTER PA\n"; + let row: DerivedDecompositionType = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x3070, 0x3071)); + assert_eq!(row.decomposition_type, "Canonical"); + } +} diff --git a/ucd-parse/src/extracted/derived_east_asian_width.rs b/ucd-parse/src/extracted/derived_east_asian_width.rs new file mode 100644 index 0000000..c4ce822 --- /dev/null +++ b/ucd-parse/src/extracted/derived_east_asian_width.rs @@ -0,0 +1,66 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedEastAsianWidth.txt` file. +/// +/// This file gives the derived values of the East_Asian_Width +/// property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedEastAsianWidth { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived East_Asian_Width of the codepoints in this entry. + pub east_asian_width: String, +} + +impl UcdFile for DerivedEastAsianWidth { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedEastAsianWidth.txt") + } +} + +impl UcdFileByCodepoint for DerivedEastAsianWidth { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedEastAsianWidth { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, east_asian_width) = + parse_codepoint_association(line)?; + Ok(DerivedEastAsianWidth { + codepoints, + east_asian_width: east_asian_width.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedEastAsianWidth; + + #[test] + fn parse_single() { + let line = "00A0 ; N # Zs NO-BREAK SPACE\n"; + let row: DerivedEastAsianWidth = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x00A0); + assert_eq!(row.east_asian_width, "N"); + } + + #[test] + fn parse_range() { + let line = "FF10..FF19 ; F # Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE\n"; + let row: DerivedEastAsianWidth = line.parse().unwrap(); + assert_eq!(row.codepoints, (0xFF10, 0xFF19)); + assert_eq!(row.east_asian_width, "F"); + } +} diff --git a/ucd-parse/src/extracted/derived_general_category.rs b/ucd-parse/src/extracted/derived_general_category.rs new file mode 100644 index 0000000..9a9710e --- /dev/null +++ b/ucd-parse/src/extracted/derived_general_category.rs @@ -0,0 +1,65 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedGeneralCategory.txt` file. +/// +/// This file gives the derived values of the General_Category property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedGeneralCategory { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived General_Category of the codepoints in this entry. + pub general_category: String, +} + +impl UcdFile for DerivedGeneralCategory { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedGeneralCategory.txt") + } +} + +impl UcdFileByCodepoint for DerivedGeneralCategory { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedGeneralCategory { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, general_category) = + parse_codepoint_association(line)?; + Ok(DerivedGeneralCategory { + codepoints, + general_category: general_category.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedGeneralCategory; + + #[test] + fn parse_single() { + let line = "04D9 ; Ll # CYRILLIC SMALL LETTER SCHWA\n"; + let row: DerivedGeneralCategory = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x04D9); + assert_eq!(row.general_category, "Ll"); + } + + #[test] + fn parse_range() { + let line = "0660..0669 ; Nd # [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE"; + let row: DerivedGeneralCategory = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x0660, 0x0669)); + assert_eq!(row.general_category, "Nd"); + } +} diff --git a/ucd-parse/src/extracted/derived_joining_group.rs b/ucd-parse/src/extracted/derived_joining_group.rs new file mode 100644 index 0000000..7707ac7 --- /dev/null +++ b/ucd-parse/src/extracted/derived_joining_group.rs @@ -0,0 +1,64 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedJoiningGroup.txt` file. +/// +/// This file gives the derived values of the Joining_Group property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedJoiningGroup { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Joining_Group of the codepoints in this entry. + pub joining_group: String, +} + +impl UcdFile for DerivedJoiningGroup { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedJoiningGroup.txt") + } +} + +impl UcdFileByCodepoint for DerivedJoiningGroup { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedJoiningGroup { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, joining_group) = parse_codepoint_association(line)?; + Ok(DerivedJoiningGroup { + codepoints, + joining_group: joining_group.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedJoiningGroup; + + #[test] + fn parse_single() { + let line = "0710 ; Alaph # Lo SYRIAC LETTER ALAPH\n"; + let row: DerivedJoiningGroup = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0710); + assert_eq!(row.joining_group, "Alaph"); + } + + #[test] + fn parse_range() { + let line = "0633..0634 ; Seen # Lo [2] ARABIC LETTER SEEN..ARABIC LETTER SHEEN\n"; + let row: DerivedJoiningGroup = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x0633, 0x0634)); + assert_eq!(row.joining_group, "Seen"); + } +} diff --git a/ucd-parse/src/extracted/derived_joining_type.rs b/ucd-parse/src/extracted/derived_joining_type.rs new file mode 100644 index 0000000..82e11b8 --- /dev/null +++ b/ucd-parse/src/extracted/derived_joining_type.rs @@ -0,0 +1,64 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedJoiningType.txt` file. +/// +/// This file gives the derived values of the Joining_Type property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedJoiningType { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Joining_Type of the codepoints in this entry. + pub joining_type: String, +} + +impl UcdFile for DerivedJoiningType { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedJoiningType.txt") + } +} + +impl UcdFileByCodepoint for DerivedJoiningType { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedJoiningType { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, joining_type) = parse_codepoint_association(line)?; + Ok(DerivedJoiningType { + codepoints, + joining_type: joining_type.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedJoiningType; + + #[test] + fn parse_single() { + let line = "0628 ; D # Lo ARABIC LETTER BEH\n"; + let row: DerivedJoiningType = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0628); + assert_eq!(row.joining_type, "D"); + } + + #[test] + fn parse_range() { + let line = "1133B..1133C ; T # Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA\n"; + let row: DerivedJoiningType = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x1133B, 0x1133C)); + assert_eq!(row.joining_type, "T"); + } +} diff --git a/ucd-parse/src/extracted/derived_line_break.rs b/ucd-parse/src/extracted/derived_line_break.rs new file mode 100644 index 0000000..dd1de43 --- /dev/null +++ b/ucd-parse/src/extracted/derived_line_break.rs @@ -0,0 +1,61 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedLineBreak.txt` file. +/// +/// This file gives the derived values of the Line_Break property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedLineBreak { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Line_Break of the codepoints in this entry. + pub line_break: String, +} + +impl UcdFile for DerivedLineBreak { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedLineBreak.txt") + } +} + +impl UcdFileByCodepoint for DerivedLineBreak { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedLineBreak { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, line_break) = parse_codepoint_association(line)?; + Ok(DerivedLineBreak { codepoints, line_break: line_break.to_string() }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedLineBreak; + + #[test] + fn parse_single() { + let line = "0028 ; OP # Ps LEFT PARENTHESIS\n"; + let row: DerivedLineBreak = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0028); + assert_eq!(row.line_break, "OP"); + } + + #[test] + fn parse_range() { + let line = "0030..0039 ; NU # Nd [10] DIGIT ZERO..DIGIT NINE\n"; + let row: DerivedLineBreak = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x0030, 0x0039)); + assert_eq!(row.line_break, "NU"); + } +} diff --git a/ucd-parse/src/extracted/derived_name.rs b/ucd-parse/src/extracted/derived_name.rs new file mode 100644 index 0000000..713a2af --- /dev/null +++ b/ucd-parse/src/extracted/derived_name.rs @@ -0,0 +1,61 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedName.txt` file. +/// +/// This file gives the derived values of the Name property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedName { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Name of the codepoints in this entry. + pub name: String, +} + +impl UcdFile for DerivedName { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedName.txt") + } +} + +impl UcdFileByCodepoint for DerivedName { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedName { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, name) = parse_codepoint_association(line)?; + Ok(DerivedName { codepoints, name: name.to_string() }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedName; + + #[test] + fn parse_single() { + let line = "0021 ; EXCLAMATION MARK\n"; + let row: DerivedName = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0021); + assert_eq!(row.name, "EXCLAMATION MARK"); + } + + #[test] + fn parse_range() { + let line = "3400..4DBF ; CJK UNIFIED IDEOGRAPH-*\n"; + let row: DerivedName = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x3400, 0x4DBF)); + assert_eq!(row.name, "CJK UNIFIED IDEOGRAPH-*"); + } +} diff --git a/ucd-parse/src/extracted/derived_numeric_type.rs b/ucd-parse/src/extracted/derived_numeric_type.rs new file mode 100644 index 0000000..554b29a --- /dev/null +++ b/ucd-parse/src/extracted/derived_numeric_type.rs @@ -0,0 +1,65 @@ +use std::path::Path; +use std::str::FromStr; + +use crate::common::{ + parse_codepoint_association, CodepointIter, Codepoints, UcdFile, + UcdFileByCodepoint, +}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedNumericType.txt` file. +/// +/// This file gives the derived values of the Numeric_Type property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedNumericType { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The derived Numeric_Type of the codepoints in this entry. + pub numeric_type: String, +} + +impl UcdFile for DerivedNumericType { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedNumericType.txt") + } +} + +impl UcdFileByCodepoint for DerivedNumericType { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedNumericType { + type Err = Error; + + fn from_str(line: &str) -> Result { + let (codepoints, numeric_type) = parse_codepoint_association(line)?; + Ok(DerivedNumericType { + codepoints, + numeric_type: numeric_type.to_string(), + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedNumericType; + + #[test] + fn parse_single() { + let line = + "2189 ; Numeric # No VULGAR FRACTION ZERO THIRDS\n"; + let row: DerivedNumericType = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x2189); + assert_eq!(row.numeric_type, "Numeric"); + } + + #[test] + fn parse_range() { + let line = "00B2..00B3 ; Digit # No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE\n"; + let row: DerivedNumericType = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x00B2, 0x00B3)); + assert_eq!(row.numeric_type, "Digit"); + } +} diff --git a/ucd-parse/src/extracted/derived_numeric_values.rs b/ucd-parse/src/extracted/derived_numeric_values.rs new file mode 100644 index 0000000..bb3c981 --- /dev/null +++ b/ucd-parse/src/extracted/derived_numeric_values.rs @@ -0,0 +1,92 @@ +use std::path::Path; +use std::str::FromStr; + +use lazy_static::lazy_static; +use regex::Regex; + +use crate::common::{CodepointIter, Codepoints, UcdFile, UcdFileByCodepoint}; +use crate::error::Error; + +/// A single row in the `extracted/DerivedNumericValues.txt` file. +/// +/// This file gives the derived values of the Numeric_Value property. +#[derive(Clone, Debug, Default, Eq, PartialEq)] +pub struct DerivedNumericValues { + /// The codepoint or codepoint range for this entry. + pub codepoints: Codepoints, + /// The approximate Numeric_Value of the codepoints in this entry, + /// as a decimal. + pub numeric_value_decimal: String, + /// The exact Numeric_Value of the codepoints in this entry, as + /// a fraction. + pub numeric_value_fraction: String, +} + +impl UcdFile for DerivedNumericValues { + fn relative_file_path() -> &'static Path { + Path::new("extracted/DerivedNumericValues.txt") + } +} + +impl UcdFileByCodepoint for DerivedNumericValues { + fn codepoints(&self) -> CodepointIter { + self.codepoints.into_iter() + } +} + +impl FromStr for DerivedNumericValues { + type Err = Error; + + fn from_str(line: &str) -> Result { + lazy_static! { + static ref PARTS: Regex = Regex::new( + r"(?x) + ^ + \s*(?P[^\s;]+)\s*; + \s*(?P[^\s;]+)\s*; + \s*; + \s*(?P[^\s;]+)\s* + " + ) + .unwrap(); + }; + + let caps = match PARTS.captures(line.trim()) { + Some(caps) => caps, + None => return err!("invalid PropList line: '{}'", line), + }; + let codepoints = caps["codepoints"].parse()?; + let numeric_value_decimal = caps["numeric_value_decimal"].to_string(); + let numeric_value_fraction = + caps["numeric_value_fraction"].to_string(); + + Ok(DerivedNumericValues { + codepoints, + numeric_value_decimal, + numeric_value_fraction, + }) + } +} + +#[cfg(test)] +mod tests { + use super::DerivedNumericValues; + + #[test] + fn parse_single() { + let line = "0030 ; 0.0 ; ; 0 # Nd DIGIT ZERO\n"; + let row: DerivedNumericValues = line.parse().unwrap(); + assert_eq!(row.codepoints, 0x0030); + assert_eq!(row.numeric_value_decimal, "0.0"); + assert_eq!(row.numeric_value_fraction, "0"); + } + + #[test] + fn parse_range() { + let line = "11FC9..11FCA ; 0.0625 ; ; 1/16 # No [2] TAMIL FRACTION ONE SIXTEENTH-1..TAMIL FRACTION ONE SIXTEENTH-2\n"; + let row: DerivedNumericValues = line.parse().unwrap(); + assert_eq!(row.codepoints, (0x11FC9, 0x11FCA)); + assert_eq!(row.numeric_value_decimal, "0.0625"); + assert_eq!(row.numeric_value_fraction, "1/16"); + } +} diff --git a/ucd-parse/src/extracted/mod.rs b/ucd-parse/src/extracted/mod.rs new file mode 100644 index 0000000..d9c532c --- /dev/null +++ b/ucd-parse/src/extracted/mod.rs @@ -0,0 +1,30 @@ +//! Structs for parsing files in the `extracted` subdirectory. +//! +//! These are placed here, rather than at the top level, to help keep +//! the number of structs in any given module managable. + +pub use self::derived_bidi_class::DerivedBidiClass; +pub use self::derived_binary_properties::DerivedBinaryProperties; +pub use self::derived_combining_class::DerivedCombiningClass; +pub use self::derived_decomposition_type::DerivedDecompositionType; +pub use self::derived_east_asian_width::DerivedEastAsianWidth; +pub use self::derived_general_category::DerivedGeneralCategory; +pub use self::derived_joining_group::DerivedJoiningGroup; +pub use self::derived_joining_type::DerivedJoiningType; +pub use self::derived_line_break::DerivedLineBreak; +pub use self::derived_name::DerivedName; +pub use self::derived_numeric_type::DerivedNumericType; +pub use self::derived_numeric_values::DerivedNumericValues; + +mod derived_bidi_class; +mod derived_binary_properties; +mod derived_combining_class; +mod derived_decomposition_type; +mod derived_east_asian_width; +mod derived_general_category; +mod derived_joining_group; +mod derived_joining_type; +mod derived_line_break; +mod derived_name; +mod derived_numeric_type; +mod derived_numeric_values; diff --git a/ucd-parse/src/lib.rs b/ucd-parse/src/lib.rs index a030ff7..f539632 100644 --- a/ucd-parse/src/lib.rs +++ b/ucd-parse/src/lib.rs @@ -43,6 +43,8 @@ macro_rules! err { } } +pub mod extracted; + mod common; mod error;