| 1 | // This file is part of ICU4X. For terms of use, please see the file |
| 2 | // called LICENSE at the top level of the ICU4X source tree |
| 3 | // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). |
| 4 | |
| 5 | //! Data and APIs for supporting specific Bidi properties data in an efficient structure. |
| 6 | //! |
| 7 | //! Supported properties are: |
| 8 | //! - `Bidi_Paired_Bracket` |
| 9 | //! - `Bidi_Paired_Bracket_Type` |
| 10 | //! - `Bidi_Mirrored` |
| 11 | //! - `Bidi_Mirroring_Glyph` |
| 12 | |
| 13 | use crate::provider::bidi_data::{ |
| 14 | BidiAuxiliaryPropertiesV1, BidiAuxiliaryPropertiesV1Marker, CheckedBidiPairedBracketType, |
| 15 | }; |
| 16 | use crate::PropertiesError; |
| 17 | |
| 18 | use icu_provider::prelude::*; |
| 19 | |
| 20 | /// A wrapper around certain Bidi properties data. Can be obtained via [`bidi_auxiliary_properties()`] and |
| 21 | /// related getters. |
| 22 | /// |
| 23 | /// Most useful methods are on [`BidiAuxiliaryPropertiesBorrowed`] obtained by calling [`BidiAuxiliaryProperties::as_borrowed()`] |
| 24 | #[derive (Debug)] |
| 25 | pub struct BidiAuxiliaryProperties { |
| 26 | data: DataPayload<BidiAuxiliaryPropertiesV1Marker>, |
| 27 | } |
| 28 | |
| 29 | impl BidiAuxiliaryProperties { |
| 30 | /// Construct a borrowed version of this type that can be queried. |
| 31 | /// |
| 32 | /// This avoids a potential small underlying cost per API call by consolidating it |
| 33 | /// up front. |
| 34 | #[inline ] |
| 35 | pub fn as_borrowed(&self) -> BidiAuxiliaryPropertiesBorrowed<'_> { |
| 36 | BidiAuxiliaryPropertiesBorrowed { |
| 37 | data: self.data.get(), |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | /// Construct a new one from loaded data |
| 42 | /// |
| 43 | /// Typically it is preferable to use getters like [`bidi_auxiliary_properties()`] instead |
| 44 | pub fn from_data(data: DataPayload<BidiAuxiliaryPropertiesV1Marker>) -> Self { |
| 45 | Self { data } |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | /// This struct represents the properties Bidi_Mirrored and Bidi_Mirroring_Glyph. |
| 50 | /// If Bidi_Mirroring_Glyph is not defined for a code point, then the value in the |
| 51 | /// struct is `None`. |
| 52 | #[derive (Debug, Eq, PartialEq)] |
| 53 | #[non_exhaustive ] |
| 54 | pub struct BidiMirroringProperties { |
| 55 | /// Represents the Bidi_Mirroring_Glyph property value |
| 56 | pub mirroring_glyph: Option<char>, |
| 57 | /// Represents the Bidi_Mirrored property value |
| 58 | pub mirrored: bool, |
| 59 | } |
| 60 | |
| 61 | /// The enum represents Bidi_Paired_Bracket_Type, the char represents Bidi_Paired_Bracket. |
| 62 | /// Bidi_Paired_Bracket has a value of `None` when Bidi_Paired_Bracket_Type is `None`. |
| 63 | #[derive (Debug, Eq, PartialEq)] |
| 64 | #[non_exhaustive ] |
| 65 | pub enum BidiPairingProperties { |
| 66 | /// Represents Bidi_Paired_Bracket_Type=Open, and the Bidi_Paired_Bracket value for that code point. |
| 67 | Open(char), |
| 68 | /// Represents Bidi_Paired_Bracket_Type=Close, and the Bidi_Paired_Bracket value for that code point. |
| 69 | Close(char), |
| 70 | /// Represents Bidi_Paired_Bracket_Type=None, which cooccurs with Bidi_Paired_Bracket |
| 71 | /// being undefined for that code point. |
| 72 | None, |
| 73 | } |
| 74 | |
| 75 | /// A borrowed wrapper around Bidi properties data, returned by |
| 76 | /// [`BidiAuxiliaryProperties::as_borrowed()`]. More efficient to query. |
| 77 | #[derive (Debug)] |
| 78 | pub struct BidiAuxiliaryPropertiesBorrowed<'a> { |
| 79 | data: &'a BidiAuxiliaryPropertiesV1<'a>, |
| 80 | } |
| 81 | |
| 82 | impl<'a> BidiAuxiliaryPropertiesBorrowed<'a> { |
| 83 | // The source data coming from icuexportdata will use 0 to represent the |
| 84 | // property value in cases for which the Bidi_Mirroring_Glyph property value |
| 85 | // of a code point is undefined. Since Rust types can be more expressive, we |
| 86 | // should represent these cases as None. |
| 87 | fn convert_mirroring_glyph_data(trie_data_char: char) -> Option<char> { |
| 88 | if trie_data_char as u32 == 0 { |
| 89 | None |
| 90 | } else { |
| 91 | Some(trie_data_char) |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | /// Return a struct for the given code point representing Bidi mirroring-related |
| 96 | /// property values. See [`BidiMirroringProperties`]. |
| 97 | /// |
| 98 | /// # Examples |
| 99 | /// ``` |
| 100 | /// use icu::properties::bidi_data; |
| 101 | /// |
| 102 | /// let bidi_data = bidi_data::bidi_auxiliary_properties(); |
| 103 | /// |
| 104 | /// let open_paren = bidi_data.get32_mirroring_props('(' as u32); |
| 105 | /// assert_eq!(open_paren.mirroring_glyph, Some(')' )); |
| 106 | /// assert_eq!(open_paren.mirrored, true); |
| 107 | /// let close_paren = bidi_data.get32_mirroring_props(')' as u32); |
| 108 | /// assert_eq!(close_paren.mirroring_glyph, Some('(' )); |
| 109 | /// assert_eq!(close_paren.mirrored, true); |
| 110 | /// let open_angle_bracket = bidi_data.get32_mirroring_props('<' as u32); |
| 111 | /// assert_eq!(open_angle_bracket.mirroring_glyph, Some('>' )); |
| 112 | /// assert_eq!(open_angle_bracket.mirrored, true); |
| 113 | /// let close_angle_bracket = bidi_data.get32_mirroring_props('>' as u32); |
| 114 | /// assert_eq!(close_angle_bracket.mirroring_glyph, Some('<' )); |
| 115 | /// assert_eq!(close_angle_bracket.mirrored, true); |
| 116 | /// let three = bidi_data.get32_mirroring_props('3' as u32); |
| 117 | /// assert_eq!(three.mirroring_glyph, None); |
| 118 | /// assert_eq!(three.mirrored, false); |
| 119 | /// ``` |
| 120 | pub fn get32_mirroring_props(&self, code_point: u32) -> BidiMirroringProperties { |
| 121 | let bidi_aux_props = self.data.trie.get32(code_point); |
| 122 | let mirroring_glyph_opt = |
| 123 | Self::convert_mirroring_glyph_data(bidi_aux_props.mirroring_glyph); |
| 124 | BidiMirroringProperties { |
| 125 | mirroring_glyph: mirroring_glyph_opt, |
| 126 | mirrored: bidi_aux_props.mirrored, |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | /// Return a struct for the given code point representing Bidi bracket |
| 131 | /// pairing-related property values. See [`BidiPairingProperties`] |
| 132 | /// |
| 133 | /// # Examples |
| 134 | /// ``` |
| 135 | /// use icu::properties::{bidi_data, bidi_data::BidiPairingProperties}; |
| 136 | /// |
| 137 | /// let bidi_data = bidi_data::bidi_auxiliary_properties(); |
| 138 | /// |
| 139 | /// let open_paren = bidi_data.get32_pairing_props('(' as u32); |
| 140 | /// assert_eq!(open_paren, BidiPairingProperties::Open(')' )); |
| 141 | /// let close_paren = bidi_data.get32_pairing_props(')' as u32); |
| 142 | /// assert_eq!(close_paren, BidiPairingProperties::Close('(' )); |
| 143 | /// let open_angle_bracket = bidi_data.get32_pairing_props('<' as u32); |
| 144 | /// assert_eq!(open_angle_bracket, BidiPairingProperties::None); |
| 145 | /// let close_angle_bracket = bidi_data.get32_pairing_props('>' as u32); |
| 146 | /// assert_eq!(close_angle_bracket, BidiPairingProperties::None); |
| 147 | /// let three = bidi_data.get32_pairing_props('3' as u32); |
| 148 | /// assert_eq!(three, BidiPairingProperties::None); |
| 149 | /// ``` |
| 150 | pub fn get32_pairing_props(&self, code_point: u32) -> BidiPairingProperties { |
| 151 | let bidi_aux_props = self.data.trie.get32(code_point); |
| 152 | let mirroring_glyph = bidi_aux_props.mirroring_glyph; |
| 153 | let paired_bracket_type = bidi_aux_props.paired_bracket_type; |
| 154 | match paired_bracket_type { |
| 155 | CheckedBidiPairedBracketType::Open => BidiPairingProperties::Open(mirroring_glyph), |
| 156 | CheckedBidiPairedBracketType::Close => BidiPairingProperties::Close(mirroring_glyph), |
| 157 | _ => BidiPairingProperties::None, |
| 158 | } |
| 159 | } |
| 160 | } |
| 161 | |
| 162 | impl BidiAuxiliaryPropertiesBorrowed<'static> { |
| 163 | /// Cheaply converts a [`BidiAuxiliaryPropertiesBorrowed<'static>`] into a [`BidiAuxiliaryProperties`]. |
| 164 | /// |
| 165 | /// Note: Due to branching and indirection, using [`BidiAuxiliaryProperties`] might inhibit some |
| 166 | /// compile-time optimizations that are possible with [`BidiAuxiliaryPropertiesBorrowed`]. |
| 167 | pub const fn static_to_owned(self) -> BidiAuxiliaryProperties { |
| 168 | BidiAuxiliaryProperties { |
| 169 | data: DataPayload::from_static_ref(self.data), |
| 170 | } |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | /// Creates a [`BidiAuxiliaryPropertiesV1`] struct that represents the data for certain |
| 175 | /// Bidi properties. |
| 176 | /// |
| 177 | /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
| 178 | /// |
| 179 | /// [📚 Help choosing a constructor](icu_provider::constructors) |
| 180 | /// |
| 181 | /// # Examples |
| 182 | /// ``` |
| 183 | /// use icu::properties::bidi_data; |
| 184 | /// |
| 185 | /// let bidi_data = bidi_data::bidi_auxiliary_properties(); |
| 186 | /// |
| 187 | /// let open_paren = bidi_data.get32_mirroring_props('(' as u32); |
| 188 | /// assert_eq!(open_paren.mirroring_glyph, Some(')' )); |
| 189 | /// assert_eq!(open_paren.mirrored, true); |
| 190 | /// ``` |
| 191 | #[cfg (feature = "compiled_data" )] |
| 192 | pub const fn bidi_auxiliary_properties() -> BidiAuxiliaryPropertiesBorrowed<'static> { |
| 193 | BidiAuxiliaryPropertiesBorrowed { |
| 194 | data: crate::provider::Baked::SINGLETON_PROPS_BIDIAUXILIARYPROPS_V1, |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | icu_provider::gen_any_buffer_data_constructors!( |
| 199 | locale: skip, |
| 200 | options: skip, |
| 201 | result: Result<BidiAuxiliaryProperties, PropertiesError>, |
| 202 | #[cfg (skip)] |
| 203 | functions: [ |
| 204 | bidi_auxiliary_properties, |
| 205 | load_bidi_auxiliary_properties_with_any_provider, |
| 206 | load_bidi_auxiliary_properties_with_buffer_provider, |
| 207 | load_bidi_auxiliary_properties_unstable, |
| 208 | ] |
| 209 | ); |
| 210 | |
| 211 | #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, bidi_auxiliary_properties)] |
| 212 | pub fn load_bidi_auxiliary_properties_unstable( |
| 213 | provider: &(impl DataProvider<BidiAuxiliaryPropertiesV1Marker> + ?Sized), |
| 214 | ) -> Result<BidiAuxiliaryProperties, PropertiesError> { |
| 215 | Ok(provider |
| 216 | .load(Default::default()) |
| 217 | .and_then(DataResponse::take_payload) |
| 218 | .map(op:BidiAuxiliaryProperties::from_data)?) |
| 219 | } |
| 220 | |