| 1 | /*! |
| 2 | |
| 3 | This library implements |
| 4 | [Unicode Bidi Mirroring](https://unicode.org/reports/tr44/#BidiMirroring.txt) property detection. |
| 5 | |
| 6 | ```rust |
| 7 | use unicode_bidi_mirroring::*; |
| 8 | |
| 9 | assert_eq!(get_mirrored('A' ), None); |
| 10 | assert_eq!(get_mirrored(' \u{2039}' ), Some(' \u{203A}' )); |
| 11 | assert_eq!(get_mirrored(' \u{203A}' ), Some(' \u{2039}' )); |
| 12 | |
| 13 | assert_eq!(is_mirroring('A' ), false); |
| 14 | assert_eq!(is_mirroring(' \u{29C4}' ), true); |
| 15 | assert_eq!(is_mirroring(' \u{22FF}' ), true); |
| 16 | ``` |
| 17 | |
| 18 | */ |
| 19 | |
| 20 | #![no_std ] |
| 21 | #![forbid (unsafe_code)] |
| 22 | |
| 23 | /// The Unicode version. |
| 24 | pub const UNICODE_VERSION: (u8, u8, u8) = (16, 0, 0); |
| 25 | |
| 26 | const PAIRS: &[(char, char)] = &[ |
| 27 | (' \u{0028}' , ' \u{0029}' ), |
| 28 | (' \u{003C}' , ' \u{003E}' ), |
| 29 | (' \u{005B}' , ' \u{005D}' ), |
| 30 | (' \u{007B}' , ' \u{007D}' ), |
| 31 | (' \u{00AB}' , ' \u{00BB}' ), |
| 32 | (' \u{0F3A}' , ' \u{0F3B}' ), |
| 33 | (' \u{0F3C}' , ' \u{0F3D}' ), |
| 34 | (' \u{169B}' , ' \u{169C}' ), |
| 35 | (' \u{2039}' , ' \u{203A}' ), |
| 36 | (' \u{2045}' , ' \u{2046}' ), |
| 37 | (' \u{207D}' , ' \u{207E}' ), |
| 38 | (' \u{208D}' , ' \u{208E}' ), |
| 39 | (' \u{2208}' , ' \u{220B}' ), |
| 40 | (' \u{2209}' , ' \u{220C}' ), |
| 41 | (' \u{220A}' , ' \u{220D}' ), |
| 42 | (' \u{2215}' , ' \u{29F5}' ), |
| 43 | (' \u{221F}' , ' \u{2BFE}' ), |
| 44 | (' \u{2220}' , ' \u{29A3}' ), |
| 45 | (' \u{2221}' , ' \u{299B}' ), |
| 46 | (' \u{2222}' , ' \u{29A0}' ), |
| 47 | (' \u{2224}' , ' \u{2AEE}' ), |
| 48 | (' \u{223C}' , ' \u{223D}' ), |
| 49 | (' \u{2243}' , ' \u{22CD}' ), |
| 50 | (' \u{2245}' , ' \u{224C}' ), |
| 51 | (' \u{2252}' , ' \u{2253}' ), |
| 52 | (' \u{2254}' , ' \u{2255}' ), |
| 53 | (' \u{2264}' , ' \u{2265}' ), |
| 54 | (' \u{2266}' , ' \u{2267}' ), |
| 55 | (' \u{2268}' , ' \u{2269}' ), |
| 56 | (' \u{226A}' , ' \u{226B}' ), |
| 57 | (' \u{226E}' , ' \u{226F}' ), |
| 58 | (' \u{2270}' , ' \u{2271}' ), |
| 59 | (' \u{2272}' , ' \u{2273}' ), |
| 60 | (' \u{2274}' , ' \u{2275}' ), |
| 61 | (' \u{2276}' , ' \u{2277}' ), |
| 62 | (' \u{2278}' , ' \u{2279}' ), |
| 63 | (' \u{227A}' , ' \u{227B}' ), |
| 64 | (' \u{227C}' , ' \u{227D}' ), |
| 65 | (' \u{227E}' , ' \u{227F}' ), |
| 66 | (' \u{2280}' , ' \u{2281}' ), |
| 67 | (' \u{2282}' , ' \u{2283}' ), |
| 68 | (' \u{2284}' , ' \u{2285}' ), |
| 69 | (' \u{2286}' , ' \u{2287}' ), |
| 70 | (' \u{2288}' , ' \u{2289}' ), |
| 71 | (' \u{228A}' , ' \u{228B}' ), |
| 72 | (' \u{228F}' , ' \u{2290}' ), |
| 73 | (' \u{2291}' , ' \u{2292}' ), |
| 74 | (' \u{2298}' , ' \u{29B8}' ), |
| 75 | (' \u{22A2}' , ' \u{22A3}' ), |
| 76 | (' \u{22A6}' , ' \u{2ADE}' ), |
| 77 | (' \u{22A8}' , ' \u{2AE4}' ), |
| 78 | (' \u{22A9}' , ' \u{2AE3}' ), |
| 79 | (' \u{22AB}' , ' \u{2AE5}' ), |
| 80 | (' \u{22B0}' , ' \u{22B1}' ), |
| 81 | (' \u{22B2}' , ' \u{22B3}' ), |
| 82 | (' \u{22B4}' , ' \u{22B5}' ), |
| 83 | (' \u{22B6}' , ' \u{22B7}' ), |
| 84 | (' \u{22B8}' , ' \u{27DC}' ), |
| 85 | (' \u{22C9}' , ' \u{22CA}' ), |
| 86 | (' \u{22CB}' , ' \u{22CC}' ), |
| 87 | (' \u{22D0}' , ' \u{22D1}' ), |
| 88 | (' \u{22D6}' , ' \u{22D7}' ), |
| 89 | (' \u{22D8}' , ' \u{22D9}' ), |
| 90 | (' \u{22DA}' , ' \u{22DB}' ), |
| 91 | (' \u{22DC}' , ' \u{22DD}' ), |
| 92 | (' \u{22DE}' , ' \u{22DF}' ), |
| 93 | (' \u{22E0}' , ' \u{22E1}' ), |
| 94 | (' \u{22E2}' , ' \u{22E3}' ), |
| 95 | (' \u{22E4}' , ' \u{22E5}' ), |
| 96 | (' \u{22E6}' , ' \u{22E7}' ), |
| 97 | (' \u{22E8}' , ' \u{22E9}' ), |
| 98 | (' \u{22EA}' , ' \u{22EB}' ), |
| 99 | (' \u{22EC}' , ' \u{22ED}' ), |
| 100 | (' \u{22F0}' , ' \u{22F1}' ), |
| 101 | (' \u{22F2}' , ' \u{22FA}' ), |
| 102 | (' \u{22F3}' , ' \u{22FB}' ), |
| 103 | (' \u{22F4}' , ' \u{22FC}' ), |
| 104 | (' \u{22F6}' , ' \u{22FD}' ), |
| 105 | (' \u{22F7}' , ' \u{22FE}' ), |
| 106 | (' \u{2308}' , ' \u{2309}' ), |
| 107 | (' \u{230A}' , ' \u{230B}' ), |
| 108 | (' \u{2329}' , ' \u{232A}' ), |
| 109 | (' \u{2768}' , ' \u{2769}' ), |
| 110 | (' \u{276A}' , ' \u{276B}' ), |
| 111 | (' \u{276C}' , ' \u{276D}' ), |
| 112 | (' \u{276E}' , ' \u{276F}' ), |
| 113 | (' \u{2770}' , ' \u{2771}' ), |
| 114 | (' \u{2772}' , ' \u{2773}' ), |
| 115 | (' \u{2774}' , ' \u{2775}' ), |
| 116 | (' \u{27C3}' , ' \u{27C4}' ), |
| 117 | (' \u{27C5}' , ' \u{27C6}' ), |
| 118 | (' \u{27C8}' , ' \u{27C9}' ), |
| 119 | (' \u{27CB}' , ' \u{27CD}' ), |
| 120 | (' \u{27D5}' , ' \u{27D6}' ), |
| 121 | (' \u{27DD}' , ' \u{27DE}' ), |
| 122 | (' \u{27E2}' , ' \u{27E3}' ), |
| 123 | (' \u{27E4}' , ' \u{27E5}' ), |
| 124 | (' \u{27E6}' , ' \u{27E7}' ), |
| 125 | (' \u{27E8}' , ' \u{27E9}' ), |
| 126 | (' \u{27EA}' , ' \u{27EB}' ), |
| 127 | (' \u{27EC}' , ' \u{27ED}' ), |
| 128 | (' \u{27EE}' , ' \u{27EF}' ), |
| 129 | (' \u{2983}' , ' \u{2984}' ), |
| 130 | (' \u{2985}' , ' \u{2986}' ), |
| 131 | (' \u{2987}' , ' \u{2988}' ), |
| 132 | (' \u{2989}' , ' \u{298A}' ), |
| 133 | (' \u{298B}' , ' \u{298C}' ), |
| 134 | (' \u{298D}' , ' \u{2990}' ), |
| 135 | (' \u{298E}' , ' \u{298F}' ), |
| 136 | (' \u{2991}' , ' \u{2992}' ), |
| 137 | (' \u{2993}' , ' \u{2994}' ), |
| 138 | (' \u{2995}' , ' \u{2996}' ), |
| 139 | (' \u{2997}' , ' \u{2998}' ), |
| 140 | (' \u{29A4}' , ' \u{29A5}' ), |
| 141 | (' \u{29A8}' , ' \u{29A9}' ), |
| 142 | (' \u{29AA}' , ' \u{29AB}' ), |
| 143 | (' \u{29AC}' , ' \u{29AD}' ), |
| 144 | (' \u{29AE}' , ' \u{29AF}' ), |
| 145 | (' \u{29C0}' , ' \u{29C1}' ), |
| 146 | (' \u{29C4}' , ' \u{29C5}' ), |
| 147 | (' \u{29CF}' , ' \u{29D0}' ), |
| 148 | (' \u{29D1}' , ' \u{29D2}' ), |
| 149 | (' \u{29D4}' , ' \u{29D5}' ), |
| 150 | (' \u{29D8}' , ' \u{29D9}' ), |
| 151 | (' \u{29DA}' , ' \u{29DB}' ), |
| 152 | (' \u{29E8}' , ' \u{29E9}' ), |
| 153 | (' \u{29F8}' , ' \u{29F9}' ), |
| 154 | (' \u{29FC}' , ' \u{29FD}' ), |
| 155 | (' \u{2A2B}' , ' \u{2A2C}' ), |
| 156 | (' \u{2A2D}' , ' \u{2A2E}' ), |
| 157 | (' \u{2A34}' , ' \u{2A35}' ), |
| 158 | (' \u{2A3C}' , ' \u{2A3D}' ), |
| 159 | (' \u{2A64}' , ' \u{2A65}' ), |
| 160 | (' \u{2A79}' , ' \u{2A7A}' ), |
| 161 | (' \u{2A7B}' , ' \u{2A7C}' ), |
| 162 | (' \u{2A7D}' , ' \u{2A7E}' ), |
| 163 | (' \u{2A7F}' , ' \u{2A80}' ), |
| 164 | (' \u{2A81}' , ' \u{2A82}' ), |
| 165 | (' \u{2A83}' , ' \u{2A84}' ), |
| 166 | (' \u{2A85}' , ' \u{2A86}' ), |
| 167 | (' \u{2A87}' , ' \u{2A88}' ), |
| 168 | (' \u{2A89}' , ' \u{2A8A}' ), |
| 169 | (' \u{2A8B}' , ' \u{2A8C}' ), |
| 170 | (' \u{2A8D}' , ' \u{2A8E}' ), |
| 171 | (' \u{2A8F}' , ' \u{2A90}' ), |
| 172 | (' \u{2A91}' , ' \u{2A92}' ), |
| 173 | (' \u{2A93}' , ' \u{2A94}' ), |
| 174 | (' \u{2A95}' , ' \u{2A96}' ), |
| 175 | (' \u{2A97}' , ' \u{2A98}' ), |
| 176 | (' \u{2A99}' , ' \u{2A9A}' ), |
| 177 | (' \u{2A9B}' , ' \u{2A9C}' ), |
| 178 | (' \u{2A9D}' , ' \u{2A9E}' ), |
| 179 | (' \u{2A9F}' , ' \u{2AA0}' ), |
| 180 | (' \u{2AA1}' , ' \u{2AA2}' ), |
| 181 | (' \u{2AA6}' , ' \u{2AA7}' ), |
| 182 | (' \u{2AA8}' , ' \u{2AA9}' ), |
| 183 | (' \u{2AAA}' , ' \u{2AAB}' ), |
| 184 | (' \u{2AAC}' , ' \u{2AAD}' ), |
| 185 | (' \u{2AAF}' , ' \u{2AB0}' ), |
| 186 | (' \u{2AB1}' , ' \u{2AB2}' ), |
| 187 | (' \u{2AB3}' , ' \u{2AB4}' ), |
| 188 | (' \u{2AB5}' , ' \u{2AB6}' ), |
| 189 | (' \u{2AB7}' , ' \u{2AB8}' ), |
| 190 | (' \u{2AB9}' , ' \u{2ABA}' ), |
| 191 | (' \u{2ABB}' , ' \u{2ABC}' ), |
| 192 | (' \u{2ABD}' , ' \u{2ABE}' ), |
| 193 | (' \u{2ABF}' , ' \u{2AC0}' ), |
| 194 | (' \u{2AC1}' , ' \u{2AC2}' ), |
| 195 | (' \u{2AC3}' , ' \u{2AC4}' ), |
| 196 | (' \u{2AC5}' , ' \u{2AC6}' ), |
| 197 | (' \u{2AC7}' , ' \u{2AC8}' ), |
| 198 | (' \u{2AC9}' , ' \u{2ACA}' ), |
| 199 | (' \u{2ACB}' , ' \u{2ACC}' ), |
| 200 | (' \u{2ACD}' , ' \u{2ACE}' ), |
| 201 | (' \u{2ACF}' , ' \u{2AD0}' ), |
| 202 | (' \u{2AD1}' , ' \u{2AD2}' ), |
| 203 | (' \u{2AD3}' , ' \u{2AD4}' ), |
| 204 | (' \u{2AD5}' , ' \u{2AD6}' ), |
| 205 | (' \u{2AEC}' , ' \u{2AED}' ), |
| 206 | (' \u{2AF7}' , ' \u{2AF8}' ), |
| 207 | (' \u{2AF9}' , ' \u{2AFA}' ), |
| 208 | (' \u{2E02}' , ' \u{2E03}' ), |
| 209 | (' \u{2E04}' , ' \u{2E05}' ), |
| 210 | (' \u{2E09}' , ' \u{2E0A}' ), |
| 211 | (' \u{2E0C}' , ' \u{2E0D}' ), |
| 212 | (' \u{2E1C}' , ' \u{2E1D}' ), |
| 213 | (' \u{2E20}' , ' \u{2E21}' ), |
| 214 | (' \u{2E22}' , ' \u{2E23}' ), |
| 215 | (' \u{2E24}' , ' \u{2E25}' ), |
| 216 | (' \u{2E26}' , ' \u{2E27}' ), |
| 217 | (' \u{2E28}' , ' \u{2E29}' ), |
| 218 | (' \u{2E55}' , ' \u{2E56}' ), |
| 219 | (' \u{2E57}' , ' \u{2E58}' ), |
| 220 | (' \u{2E59}' , ' \u{2E5A}' ), |
| 221 | (' \u{2E5B}' , ' \u{2E5C}' ), |
| 222 | (' \u{3008}' , ' \u{3009}' ), |
| 223 | (' \u{300A}' , ' \u{300B}' ), |
| 224 | (' \u{300C}' , ' \u{300D}' ), |
| 225 | (' \u{300E}' , ' \u{300F}' ), |
| 226 | (' \u{3010}' , ' \u{3011}' ), |
| 227 | (' \u{3014}' , ' \u{3015}' ), |
| 228 | (' \u{3016}' , ' \u{3017}' ), |
| 229 | (' \u{3018}' , ' \u{3019}' ), |
| 230 | (' \u{301A}' , ' \u{301B}' ), |
| 231 | (' \u{FE59}' , ' \u{FE5A}' ), |
| 232 | (' \u{FE5B}' , ' \u{FE5C}' ), |
| 233 | (' \u{FE5D}' , ' \u{FE5E}' ), |
| 234 | (' \u{FE64}' , ' \u{FE65}' ), |
| 235 | (' \u{FF08}' , ' \u{FF09}' ), |
| 236 | (' \u{FF1C}' , ' \u{FF1E}' ), |
| 237 | (' \u{FF3B}' , ' \u{FF3D}' ), |
| 238 | (' \u{FF5B}' , ' \u{FF5D}' ), |
| 239 | (' \u{FF5F}' , ' \u{FF60}' ), |
| 240 | (' \u{FF62}' , ' \u{FF63}' ), |
| 241 | ]; |
| 242 | |
| 243 | const OTHER: &[char] = &[ |
| 244 | ' \u{2140}' , |
| 245 | ' \u{2201}' , |
| 246 | ' \u{2202}' , |
| 247 | ' \u{2203}' , |
| 248 | ' \u{2204}' , |
| 249 | ' \u{2211}' , |
| 250 | ' \u{2216}' , |
| 251 | ' \u{221A}' , |
| 252 | ' \u{221B}' , |
| 253 | ' \u{221C}' , |
| 254 | ' \u{221D}' , |
| 255 | ' \u{2226}' , |
| 256 | ' \u{222B}' , |
| 257 | ' \u{222C}' , |
| 258 | ' \u{222D}' , |
| 259 | ' \u{222E}' , |
| 260 | ' \u{222F}' , |
| 261 | ' \u{2230}' , |
| 262 | ' \u{2231}' , |
| 263 | ' \u{2232}' , |
| 264 | ' \u{2233}' , |
| 265 | ' \u{2239}' , |
| 266 | ' \u{223B}' , |
| 267 | ' \u{223E}' , |
| 268 | ' \u{223F}' , |
| 269 | ' \u{2240}' , |
| 270 | ' \u{2241}' , |
| 271 | ' \u{2242}' , |
| 272 | ' \u{2244}' , |
| 273 | ' \u{2246}' , |
| 274 | ' \u{2247}' , |
| 275 | ' \u{2248}' , |
| 276 | ' \u{2249}' , |
| 277 | ' \u{224A}' , |
| 278 | ' \u{224B}' , |
| 279 | ' \u{225F}' , |
| 280 | ' \u{2260}' , |
| 281 | ' \u{2262}' , |
| 282 | ' \u{226D}' , |
| 283 | ' \u{228C}' , |
| 284 | ' \u{22A7}' , |
| 285 | ' \u{22AA}' , |
| 286 | ' \u{22AC}' , |
| 287 | ' \u{22AD}' , |
| 288 | ' \u{22AE}' , |
| 289 | ' \u{22AF}' , |
| 290 | ' \u{22BE}' , |
| 291 | ' \u{22BF}' , |
| 292 | ' \u{22F5}' , |
| 293 | ' \u{22F8}' , |
| 294 | ' \u{22F9}' , |
| 295 | ' \u{22FF}' , |
| 296 | ' \u{2320}' , |
| 297 | ' \u{2321}' , |
| 298 | ' \u{27C0}' , |
| 299 | ' \u{27CC}' , |
| 300 | ' \u{27D3}' , |
| 301 | ' \u{27D4}' , |
| 302 | ' \u{299C}' , |
| 303 | ' \u{299D}' , |
| 304 | ' \u{299E}' , |
| 305 | ' \u{299F}' , |
| 306 | ' \u{29A2}' , |
| 307 | ' \u{29A6}' , |
| 308 | ' \u{29A7}' , |
| 309 | ' \u{29C2}' , |
| 310 | ' \u{29C3}' , |
| 311 | ' \u{29C9}' , |
| 312 | ' \u{29CE}' , |
| 313 | ' \u{29DC}' , |
| 314 | ' \u{29E1}' , |
| 315 | ' \u{29E3}' , |
| 316 | ' \u{29E4}' , |
| 317 | ' \u{29E5}' , |
| 318 | ' \u{29F4}' , |
| 319 | ' \u{29F6}' , |
| 320 | ' \u{29F7}' , |
| 321 | ' \u{2A0A}' , |
| 322 | ' \u{2A0B}' , |
| 323 | ' \u{2A0C}' , |
| 324 | ' \u{2A0D}' , |
| 325 | ' \u{2A0E}' , |
| 326 | ' \u{2A0F}' , |
| 327 | ' \u{2A10}' , |
| 328 | ' \u{2A11}' , |
| 329 | ' \u{2A12}' , |
| 330 | ' \u{2A13}' , |
| 331 | ' \u{2A14}' , |
| 332 | ' \u{2A15}' , |
| 333 | ' \u{2A16}' , |
| 334 | ' \u{2A17}' , |
| 335 | ' \u{2A18}' , |
| 336 | ' \u{2A19}' , |
| 337 | ' \u{2A1A}' , |
| 338 | ' \u{2A1B}' , |
| 339 | ' \u{2A1C}' , |
| 340 | ' \u{2A1E}' , |
| 341 | ' \u{2A1F}' , |
| 342 | ' \u{2A20}' , |
| 343 | ' \u{2A21}' , |
| 344 | ' \u{2A24}' , |
| 345 | ' \u{2A26}' , |
| 346 | ' \u{2A29}' , |
| 347 | ' \u{2A3E}' , |
| 348 | ' \u{2A57}' , |
| 349 | ' \u{2A58}' , |
| 350 | ' \u{2A6A}' , |
| 351 | ' \u{2A6B}' , |
| 352 | ' \u{2A6C}' , |
| 353 | ' \u{2A6D}' , |
| 354 | ' \u{2A6F}' , |
| 355 | ' \u{2A70}' , |
| 356 | ' \u{2A73}' , |
| 357 | ' \u{2A74}' , |
| 358 | ' \u{2AA3}' , |
| 359 | ' \u{2ADC}' , |
| 360 | ' \u{2AE2}' , |
| 361 | ' \u{2AE6}' , |
| 362 | ' \u{2AF3}' , |
| 363 | ' \u{2AFB}' , |
| 364 | ' \u{2AFD}' , |
| 365 | ' \u{1D6DB}' , |
| 366 | ' \u{1D715}' , |
| 367 | ' \u{1D74F}' , |
| 368 | ' \u{1D789}' , |
| 369 | ' \u{1D7C3}' , |
| 370 | ]; |
| 371 | |
| 372 | /// Returns a bidi mirrored character. |
| 373 | /// |
| 374 | /// Based on <https://www.unicode.org/Public/UNIDATA/BidiMirroring.txt>. |
| 375 | pub fn get_mirrored(c: char) -> Option<char> { |
| 376 | if let Ok(idx: usize) = PAIRS.binary_search_by(|v: &(char, char)| v.0.cmp(&c)) { |
| 377 | return Some(PAIRS[idx].1); |
| 378 | } |
| 379 | |
| 380 | if let Ok(idx: usize) = PAIRS.binary_search_by(|v: &(char, char)| v.1.cmp(&c)) { |
| 381 | return Some(PAIRS[idx].0); |
| 382 | } |
| 383 | |
| 384 | None |
| 385 | } |
| 386 | |
| 387 | /// Checks that character is bidi mirrored. |
| 388 | /// |
| 389 | /// Based on <https://www.unicode.org/Public/UNIDATA/BidiMirroring.txt>. |
| 390 | pub fn is_mirroring(c: char) -> bool { |
| 391 | PAIRS.binary_search_by(|v: &(char, char)| v.0.cmp(&c)).is_ok() || |
| 392 | PAIRS.binary_search_by(|v: &(char, char)| v.1.cmp(&c)).is_ok() || |
| 393 | OTHER.binary_search_by(|v: &char| v.cmp(&c)).is_ok() |
| 394 | } |
| 395 | |