Coverage Report

Created: 2026-02-14 06:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/src/names.rs
Line
Count
Source
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
use crate::props::*;
6
use crate::provider::names::*;
7
use core::marker::PhantomData;
8
use icu_collections::codepointtrie::TrieValue;
9
use icu_provider::marker::ErasedMarker;
10
use icu_provider::prelude::*;
11
use yoke::Yokeable;
12
use zerotrie::cursor::ZeroTrieSimpleAsciiCursor;
13
14
/// A struct capable of looking up a property value from a string name.
15
/// Access its data by calling [`Self::as_borrowed()`] and using the methods on
16
/// [`PropertyParserBorrowed`].
17
///
18
/// The name can be a short name (`Lu`), a long name(`Uppercase_Letter`),
19
/// or an alias.
20
///
21
/// Property names can be looked up using "strict" matching (looking for a name
22
/// that matches exactly), or "loose matching", where the name is allowed to deviate
23
/// in terms of ASCII casing, whitespace, underscores, and hyphens.
24
///
25
/// # Example
26
///
27
/// ```
28
/// use icu::properties::props::GeneralCategory;
29
/// use icu::properties::PropertyParser;
30
///
31
/// let lookup = PropertyParser::<GeneralCategory>::new();
32
/// // short name for value
33
/// assert_eq!(
34
///     lookup.get_strict("Lu"),
35
///     Some(GeneralCategory::UppercaseLetter)
36
/// );
37
/// assert_eq!(
38
///     lookup.get_strict("Pd"),
39
///     Some(GeneralCategory::DashPunctuation)
40
/// );
41
/// // long name for value
42
/// assert_eq!(
43
///     lookup.get_strict("Uppercase_Letter"),
44
///     Some(GeneralCategory::UppercaseLetter)
45
/// );
46
/// assert_eq!(
47
///     lookup.get_strict("Dash_Punctuation"),
48
///     Some(GeneralCategory::DashPunctuation)
49
/// );
50
/// // name has incorrect casing
51
/// assert_eq!(lookup.get_strict("dashpunctuation"), None);
52
/// // loose matching of name
53
/// assert_eq!(
54
///     lookup.get_loose("dash-punctuation"),
55
///     Some(GeneralCategory::DashPunctuation)
56
/// );
57
/// // fake property
58
/// assert_eq!(lookup.get_strict("Animated_Gif"), None);
59
/// ```
60
#[derive(Debug)]
61
pub struct PropertyParser<T> {
62
    map: DataPayload<ErasedMarker<PropertyValueNameToEnumMap<'static>>>,
63
    markers: PhantomData<fn() -> T>,
64
}
65
66
/// A borrowed wrapper around property value name-to-enum data, returned by
67
/// [`PropertyParser::as_borrowed()`]. More efficient to query.
68
#[derive(Debug)]
69
pub struct PropertyParserBorrowed<'a, T> {
70
    map: &'a PropertyValueNameToEnumMap<'a>,
71
    markers: PhantomData<fn() -> T>,
72
}
73
74
impl<T> Clone for PropertyParserBorrowed<'_, T> {
75
    fn clone(&self) -> Self {
76
        *self
77
    }
78
}
79
impl<T> Copy for PropertyParserBorrowed<'_, T> {}
80
81
impl<T> PropertyParser<T> {
82
    /// Creates a new instance of `PropertyParser<T>` using compiled data.
83
    ///
84
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
85
    ///
86
    /// [📚 Help choosing a constructor](icu_provider::constructors)
87
    #[cfg(feature = "compiled_data")]
88
    #[expect(clippy::new_ret_no_self)]
89
0
    pub fn new() -> PropertyParserBorrowed<'static, T>
90
0
    where
91
0
        T: ParseableEnumeratedProperty,
92
    {
93
0
        PropertyParserBorrowed::new()
94
0
    }
95
96
    #[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::new)]
97
    pub fn try_new_unstable(
98
        provider: &(impl DataProvider<T::DataMarker> + ?Sized),
99
    ) -> Result<Self, DataError>
100
    where
101
        T: ParseableEnumeratedProperty,
102
    {
103
        Ok(Self {
104
            map: provider.load(Default::default())?.payload.cast(),
105
            markers: PhantomData,
106
        })
107
    }
108
109
    /// Construct a borrowed version of this type that can be queried.
110
    ///
111
    /// This avoids a potential small underlying cost per API call (like `get_strict()`) by consolidating it
112
    /// up front.
113
    #[inline]
114
    pub fn as_borrowed(&self) -> PropertyParserBorrowed<'_, T> {
115
        PropertyParserBorrowed {
116
            map: self.map.get(),
117
            markers: PhantomData,
118
        }
119
    }
120
121
    #[doc(hidden)] // used by FFI code
122
    pub fn erase(self) -> PropertyParser<u16> {
123
        PropertyParser {
124
            map: self.map.cast(),
125
            markers: PhantomData,
126
        }
127
    }
128
}
129
130
impl<T: TrieValue> PropertyParserBorrowed<'_, T> {
131
    /// Get the property value as a u16, doing a strict search looking for
132
    /// names that match exactly
133
    ///
134
    /// # Example
135
    ///
136
    /// ```
137
    /// use icu::properties::props::GeneralCategory;
138
    /// use icu::properties::PropertyParser;
139
    ///
140
    /// let lookup = PropertyParser::<GeneralCategory>::new();
141
    /// assert_eq!(
142
    ///     lookup.get_strict_u16("Lu"),
143
    ///     Some(GeneralCategory::UppercaseLetter as u16)
144
    /// );
145
    /// assert_eq!(
146
    ///     lookup.get_strict_u16("Uppercase_Letter"),
147
    ///     Some(GeneralCategory::UppercaseLetter as u16)
148
    /// );
149
    /// // does not do loose matching
150
    /// assert_eq!(lookup.get_strict_u16("UppercaseLetter"), None);
151
    /// ```
152
    #[inline]
153
0
    pub fn get_strict_u16(self, name: &str) -> Option<u16> {
154
0
        get_strict_u16(self.map, name)
155
0
    }
156
157
    /// Get the property value as a `T`, doing a strict search looking for
158
    /// names that match exactly
159
    ///
160
    /// # Example
161
    ///
162
    /// ```
163
    /// use icu::properties::props::GeneralCategory;
164
    /// use icu::properties::PropertyParser;
165
    ///
166
    /// let lookup = PropertyParser::<GeneralCategory>::new();
167
    /// assert_eq!(
168
    ///     lookup.get_strict("Lu"),
169
    ///     Some(GeneralCategory::UppercaseLetter)
170
    /// );
171
    /// assert_eq!(
172
    ///     lookup.get_strict("Uppercase_Letter"),
173
    ///     Some(GeneralCategory::UppercaseLetter)
174
    /// );
175
    /// // does not do loose matching
176
    /// assert_eq!(lookup.get_strict("UppercaseLetter"), None);
177
    /// ```
178
    #[inline]
179
0
    pub fn get_strict(self, name: &str) -> Option<T> {
180
0
        T::try_from_u32(self.get_strict_u16(name)? as u32).ok()
181
0
    }
182
183
    /// Get the property value as a u16, doing a loose search looking for
184
    /// names that match case-insensitively, ignoring ASCII hyphens, underscores, and
185
    /// whitespaces.
186
    ///
187
    /// # Example
188
    ///
189
    /// ```
190
    /// use icu::properties::props::GeneralCategory;
191
    /// use icu::properties::PropertyParser;
192
    ///
193
    /// let lookup = PropertyParser::<GeneralCategory>::new();
194
    /// assert_eq!(
195
    ///     lookup.get_loose_u16("Lu"),
196
    ///     Some(GeneralCategory::UppercaseLetter as u16)
197
    /// );
198
    /// assert_eq!(
199
    ///     lookup.get_loose_u16("Uppercase_Letter"),
200
    ///     Some(GeneralCategory::UppercaseLetter as u16)
201
    /// );
202
    /// // does do loose matching
203
    /// assert_eq!(
204
    ///     lookup.get_loose_u16("UppercaseLetter"),
205
    ///     Some(GeneralCategory::UppercaseLetter as u16)
206
    /// );
207
    /// ```
208
    #[inline]
209
    pub fn get_loose_u16(self, name: &str) -> Option<u16> {
210
        get_loose_u16(self.map, name)
211
    }
212
213
    /// Get the property value as a `T`, doing a loose search looking for
214
    /// names that match case-insensitively, ignoring ASCII hyphens, underscores, and
215
    /// whitespaces.
216
    ///
217
    /// # Example
218
    ///
219
    /// ```
220
    /// use icu::properties::props::GeneralCategory;
221
    /// use icu::properties::PropertyParser;
222
    ///
223
    /// let lookup = PropertyParser::<GeneralCategory>::new();
224
    /// assert_eq!(
225
    ///     lookup.get_loose("Lu"),
226
    ///     Some(GeneralCategory::UppercaseLetter)
227
    /// );
228
    /// assert_eq!(
229
    ///     lookup.get_loose("Uppercase_Letter"),
230
    ///     Some(GeneralCategory::UppercaseLetter)
231
    /// );
232
    /// // does do loose matching
233
    /// assert_eq!(
234
    ///     lookup.get_loose("UppercaseLetter"),
235
    ///     Some(GeneralCategory::UppercaseLetter)
236
    /// );
237
    /// ```
238
    #[inline]
239
    pub fn get_loose(self, name: &str) -> Option<T> {
240
        T::try_from_u32(self.get_loose_u16(name)? as u32).ok()
241
    }
242
}
243
244
#[cfg(feature = "compiled_data")]
245
impl<T: ParseableEnumeratedProperty> Default for PropertyParserBorrowed<'static, T> {
246
    fn default() -> Self {
247
        Self::new()
248
    }
249
}
250
251
impl<T: TrieValue> PropertyParserBorrowed<'static, T> {
252
    /// Creates a new instance of `PropertyParserBorrowed<T>` using compiled data.
253
    ///
254
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
255
    ///
256
    /// [📚 Help choosing a constructor](icu_provider::constructors)
257
    #[cfg(feature = "compiled_data")]
258
0
    pub fn new() -> Self
259
0
    where
260
0
        T: ParseableEnumeratedProperty,
261
    {
262
0
        Self {
263
0
            map: T::SINGLETON,
264
0
            markers: PhantomData,
265
0
        }
266
0
    }
267
268
    /// Cheaply converts a [`PropertyParserBorrowed<'static>`] into a [`PropertyParser`].
269
    ///
270
    /// Note: Due to branching and indirection, using [`PropertyParser`] might inhibit some
271
    /// compile-time optimizations that are possible with [`PropertyParserBorrowed`].
272
    pub const fn static_to_owned(self) -> PropertyParser<T> {
273
        PropertyParser {
274
            map: DataPayload::from_static_ref(self.map),
275
            markers: PhantomData,
276
        }
277
    }
278
}
279
280
/// Avoid monomorphizing multiple copies of this function
281
0
fn get_strict_u16(payload: &PropertyValueNameToEnumMap<'_>, name: &str) -> Option<u16> {
282
0
    payload.map.get(name).and_then(|i| i.try_into().ok())
283
0
}
284
285
/// Avoid monomorphizing multiple copies of this function
286
0
fn get_loose_u16(payload: &PropertyValueNameToEnumMap<'_>, name: &str) -> Option<u16> {
287
0
    fn recurse(mut cursor: ZeroTrieSimpleAsciiCursor, mut rest: &[u8]) -> Option<usize> {
288
0
        if cursor.is_empty() {
289
0
            return None;
290
0
        }
291
292
        // Skip whitespace, underscore, hyphen in trie.
293
0
        for skip in [b'\t', b'\n', b'\x0C', b'\r', b' ', 0x0B, b'_', b'-'] {
294
0
            let mut skip_cursor = cursor.clone();
295
0
            skip_cursor.step(skip);
296
0
            if let Some(r) = recurse(skip_cursor, rest) {
297
0
                return Some(r);
298
0
            }
299
        }
300
301
0
        let ascii = loop {
302
0
            let Some((&a, r)) = rest.split_first() else {
303
0
                return cursor.take_value();
304
            };
305
0
            rest = r;
306
307
            // Skip whitespace, underscore, hyphen in input
308
0
            if !matches!(
309
0
                a,
310
                b'\t' | b'\n' | b'\x0C' | b'\r' | b' ' | 0x0B | b'_' | b'-'
311
            ) {
312
0
                break a;
313
0
            }
314
        };
315
316
0
        let mut other_case_cursor = cursor.clone();
317
0
        cursor.step(ascii);
318
0
        other_case_cursor.step(if ascii.is_ascii_lowercase() {
319
0
            ascii.to_ascii_uppercase()
320
        } else {
321
0
            ascii.to_ascii_lowercase()
322
        });
323
        // This uses the call stack as the DFS stack. The recursion will terminate as
324
        // rest's length is strictly shrinking. The call stack's depth is limited by
325
        // name.len().
326
0
        recurse(cursor, rest).or_else(|| recurse(other_case_cursor, rest))
327
0
    }
328
329
0
    recurse(payload.map.cursor(), name.as_bytes()).and_then(|i| i.try_into().ok())
330
0
}
331
332
/// A struct capable of looking up a property name from a value
333
/// Access its data by calling [`Self::as_borrowed()`] and using the methods on
334
/// [`PropertyNamesLongBorrowed`].
335
///
336
/// # Example
337
///
338
/// ```
339
/// use icu::properties::props::CanonicalCombiningClass;
340
/// use icu::properties::PropertyNamesLong;
341
///
342
/// let names = PropertyNamesLong::<CanonicalCombiningClass>::new();
343
/// assert_eq!(
344
///     names.get(CanonicalCombiningClass::KanaVoicing),
345
///     Some("Kana_Voicing")
346
/// );
347
/// assert_eq!(
348
///     names.get(CanonicalCombiningClass::AboveLeft),
349
///     Some("Above_Left")
350
/// );
351
/// ```
352
pub struct PropertyNamesLong<T: NamedEnumeratedProperty> {
353
    map: DataPayload<ErasedMarker<T::DataStructLong>>,
354
}
355
356
impl<T: NamedEnumeratedProperty> core::fmt::Debug for PropertyNamesLong<T> {
357
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
358
        f.debug_struct("PropertyNamesLong")
359
            // .field("map", &self.map)
360
            .finish()
361
    }
362
}
363
364
/// A borrowed wrapper around property value name-to-enum data, returned by
365
/// [`PropertyNamesLong::as_borrowed()`]. More efficient to query.
366
#[derive(Debug)]
367
pub struct PropertyNamesLongBorrowed<'a, T: NamedEnumeratedProperty> {
368
    map: &'a T::DataStructLongBorrowed<'a>,
369
}
370
371
impl<T: NamedEnumeratedProperty> Clone for PropertyNamesLongBorrowed<'_, T> {
372
    fn clone(&self) -> Self {
373
        *self
374
    }
375
}
376
impl<T: NamedEnumeratedProperty> Copy for PropertyNamesLongBorrowed<'_, T> {}
377
378
impl<T: NamedEnumeratedProperty> PropertyNamesLong<T> {
379
    /// Creates a new instance of `PropertyNamesLongBorrowed<T>`.
380
    ///
381
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
382
    ///
383
    /// [📚 Help choosing a constructor](icu_provider::constructors)
384
    #[cfg(feature = "compiled_data")]
385
    #[expect(clippy::new_ret_no_self)]
386
    pub fn new() -> PropertyNamesLongBorrowed<'static, T> {
387
        PropertyNamesLongBorrowed::new()
388
    }
389
390
    #[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::new)]
391
    pub fn try_new_unstable(
392
        provider: &(impl DataProvider<T::DataMarkerLong> + ?Sized),
393
    ) -> Result<Self, DataError> {
394
        Ok(Self {
395
            map: provider.load(Default::default())?.payload.cast(),
396
        })
397
    }
398
399
    /// Construct a borrowed version of this type that can be queried.
400
    ///
401
    /// This avoids a potential small underlying cost per API call (like `get_static()`) by consolidating it
402
    /// up front.
403
    #[inline]
404
    pub fn as_borrowed(&self) -> PropertyNamesLongBorrowed<'_, T> {
405
        PropertyNamesLongBorrowed {
406
            map: T::nep_long_identity(self.map.get()),
407
        }
408
    }
409
}
410
411
impl<'a, T: NamedEnumeratedProperty> PropertyNamesLongBorrowed<'a, T> {
412
    /// Get the property name given a value
413
    ///
414
    /// # Example
415
    ///
416
    /// ```rust
417
    /// use icu::properties::props::CanonicalCombiningClass;
418
    /// use icu::properties::PropertyNamesLong;
419
    ///
420
    /// let lookup = PropertyNamesLong::<CanonicalCombiningClass>::new();
421
    /// assert_eq!(
422
    ///     lookup.get(CanonicalCombiningClass::KanaVoicing),
423
    ///     Some("Kana_Voicing")
424
    /// );
425
    /// assert_eq!(
426
    ///     lookup.get(CanonicalCombiningClass::AboveLeft),
427
    ///     Some("Above_Left")
428
    /// );
429
    /// ```
430
    #[inline]
431
    pub fn get(self, property: T) -> Option<&'a str> {
432
        self.map.get(property.to_u32())
433
    }
434
}
435
436
#[cfg(feature = "compiled_data")]
437
impl<T: NamedEnumeratedProperty> Default for PropertyNamesLongBorrowed<'static, T> {
438
    fn default() -> Self {
439
        Self::new()
440
    }
441
}
442
443
impl<T: NamedEnumeratedProperty> PropertyNamesLongBorrowed<'static, T> {
444
    /// Creates a new instance of `PropertyNamesLongBorrowed<T>`.
445
    ///
446
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
447
    ///
448
    /// [📚 Help choosing a constructor](icu_provider::constructors)
449
    #[cfg(feature = "compiled_data")]
450
    pub fn new() -> Self {
451
        Self {
452
            map: T::SINGLETON_LONG,
453
        }
454
    }
455
456
    /// Cheaply converts a [`PropertyNamesLongBorrowed<'static>`] into a [`PropertyNamesLong`].
457
    ///
458
    /// Note: Due to branching and indirection, using [`PropertyNamesLong`] might inhibit some
459
    /// compile-time optimizations that are possible with [`PropertyNamesLongBorrowed`].
460
    ///
461
    /// This is currently not `const` unlike other `static_to_owned()` functions since it needs
462
    /// const traits to do that safely
463
    pub fn static_to_owned(self) -> PropertyNamesLong<T> {
464
        PropertyNamesLong {
465
            map: DataPayload::from_static_ref(T::nep_long_identity_static(self.map)),
466
        }
467
    }
468
}
469
470
/// A struct capable of looking up a property name from a value
471
/// Access its data by calling [`Self::as_borrowed()`] and using the methods on
472
/// [`PropertyNamesShortBorrowed`].
473
///
474
/// # Example
475
///
476
/// ```
477
/// use icu::properties::props::CanonicalCombiningClass;
478
/// use icu::properties::PropertyNamesShort;
479
///
480
/// let names = PropertyNamesShort::<CanonicalCombiningClass>::new();
481
/// assert_eq!(names.get(CanonicalCombiningClass::KanaVoicing), Some("KV"));
482
/// assert_eq!(names.get(CanonicalCombiningClass::AboveLeft), Some("AL"));
483
/// ```
484
pub struct PropertyNamesShort<T: NamedEnumeratedProperty> {
485
    map: DataPayload<ErasedMarker<T::DataStructShort>>,
486
}
487
488
impl<T: NamedEnumeratedProperty> core::fmt::Debug for PropertyNamesShort<T> {
489
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
490
        f.debug_struct("PropertyNamesShort")
491
            // .field("map", &self.map)
492
            .finish()
493
    }
494
}
495
496
/// A borrowed wrapper around property value name-to-enum data, returned by
497
/// [`PropertyNamesShort::as_borrowed()`]. More efficient to query.
498
#[derive(Debug)]
499
pub struct PropertyNamesShortBorrowed<'a, T: NamedEnumeratedProperty> {
500
    map: &'a T::DataStructShortBorrowed<'a>,
501
}
502
503
impl<T: NamedEnumeratedProperty> Clone for PropertyNamesShortBorrowed<'_, T> {
504
    fn clone(&self) -> Self {
505
        *self
506
    }
507
}
508
509
impl<T: NamedEnumeratedProperty> Copy for PropertyNamesShortBorrowed<'_, T> {}
510
511
impl<T: NamedEnumeratedProperty> PropertyNamesShort<T> {
512
    /// Creates a new instance of `PropertyNamesShortBorrowed<T>`.
513
    ///
514
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
515
    ///
516
    /// [📚 Help choosing a constructor](icu_provider::constructors)
517
    #[cfg(feature = "compiled_data")]
518
    #[expect(clippy::new_ret_no_self)]
519
0
    pub fn new() -> PropertyNamesShortBorrowed<'static, T> {
520
0
        PropertyNamesShortBorrowed::new()
521
0
    }
522
523
    #[doc = icu_provider::gen_buffer_unstable_docs!(UNSTABLE, Self::new)]
524
    pub fn try_new_unstable(
525
        provider: &(impl DataProvider<T::DataMarkerShort> + ?Sized),
526
    ) -> Result<Self, DataError> {
527
        Ok(Self {
528
            map: provider.load(Default::default())?.payload.cast(),
529
        })
530
    }
531
532
    /// Construct a borrowed version of this type that can be queried.
533
    ///
534
    /// This avoids a potential small underlying cost per API call (like `get_static()`) by consolidating it
535
    /// up front.
536
    #[inline]
537
    pub fn as_borrowed(&self) -> PropertyNamesShortBorrowed<'_, T> {
538
        PropertyNamesShortBorrowed {
539
            map: T::nep_short_identity(self.map.get()),
540
        }
541
    }
542
}
543
544
impl<'a, T: NamedEnumeratedProperty> PropertyNamesShortBorrowed<'a, T> {
545
    /// Get the property name given a value
546
    ///
547
    /// # Example
548
    ///
549
    /// ```rust
550
    /// use icu::properties::props::CanonicalCombiningClass;
551
    /// use icu::properties::PropertyNamesShort;
552
    ///
553
    /// let lookup = PropertyNamesShort::<CanonicalCombiningClass>::new();
554
    /// assert_eq!(lookup.get(CanonicalCombiningClass::KanaVoicing), Some("KV"));
555
    /// assert_eq!(lookup.get(CanonicalCombiningClass::AboveLeft), Some("AL"));
556
    /// ```
557
    #[inline]
558
    pub fn get(self, property: T) -> Option<&'a str> {
559
        self.map.get(property.to_u32())
560
    }
561
}
562
563
impl PropertyNamesShortBorrowed<'_, Script> {
564
    /// Gets the "name" of a script property as a `icu::locale::subtags::Script`.
565
    ///
566
    /// This method is available only on `PropertyNamesShortBorrowed<Script>`.
567
    ///
568
    /// # Example
569
    ///
570
    /// ```rust
571
    /// use icu::locale::subtags::script;
572
    /// use icu::properties::props::Script;
573
    /// use icu::properties::PropertyNamesShort;
574
    ///
575
    /// let lookup = PropertyNamesShort::<Script>::new();
576
    /// assert_eq!(
577
    ///     lookup.get_locale_script(Script::Brahmi),
578
    ///     Some(script!("Brah"))
579
    /// );
580
    /// assert_eq!(
581
    ///     lookup.get_locale_script(Script::Hangul),
582
    ///     Some(script!("Hang"))
583
    /// );
584
    /// ```
585
    ///
586
    /// For the reverse direction, use property parsing as normal:
587
    /// ```
588
    /// use icu::locale::subtags::script;
589
    /// use icu::properties::props::Script;
590
    /// use icu::properties::PropertyParser;
591
    ///
592
    /// let parser = PropertyParser::<Script>::new();
593
    /// assert_eq!(
594
    ///     parser.get_strict(script!("Brah").as_str()),
595
    ///     Some(Script::Brahmi)
596
    /// );
597
    /// assert_eq!(
598
    ///     parser.get_strict(script!("Hang").as_str()),
599
    ///     Some(Script::Hangul)
600
    /// );
601
    /// ```
602
    #[inline]
603
0
    pub fn get_locale_script(self, property: Script) -> Option<icu_locale_core::subtags::Script> {
604
0
        let prop = usize::try_from(property.to_u32()).ok()?;
605
0
        self.map.map.get(prop).and_then(|o| o.0)
606
0
    }
607
}
608
609
#[cfg(feature = "compiled_data")]
610
impl<T: NamedEnumeratedProperty> Default for PropertyNamesShortBorrowed<'static, T> {
611
    fn default() -> Self {
612
        Self::new()
613
    }
614
}
615
616
impl<T: NamedEnumeratedProperty> PropertyNamesShortBorrowed<'static, T> {
617
    /// Creates a new instance of `PropertyNamesShortBorrowed<T>`.
618
    ///
619
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
620
    ///
621
    /// [📚 Help choosing a constructor](icu_provider::constructors)
622
    #[cfg(feature = "compiled_data")]
623
0
    pub fn new() -> Self {
624
0
        Self {
625
0
            map: T::SINGLETON_SHORT,
626
0
        }
627
0
    }
628
629
    /// Cheaply converts a [`PropertyNamesShortBorrowed<'static>`] into a [`PropertyNamesShort`].
630
    ///
631
    /// Note: Due to branching and indirection, using [`PropertyNamesShort`] might inhibit some
632
    /// compile-time optimizations that are possible with [`PropertyNamesShortBorrowed`].
633
    ///
634
    /// This is currently not `const` unlike other `static_to_owned()` functions since it needs
635
    /// const traits to do that safely
636
    pub fn static_to_owned(self) -> PropertyNamesShort<T> {
637
        PropertyNamesShort {
638
            map: DataPayload::from_static_ref(T::nep_short_identity_static(self.map)),
639
        }
640
    }
641
}
642
643
/// A property whose value names can be parsed from strings.
644
pub trait ParseableEnumeratedProperty: crate::private::Sealed + TrieValue {
645
    #[doc(hidden)]
646
    type DataMarker: DataMarker<DataStruct = PropertyValueNameToEnumMap<'static>>;
647
    #[doc(hidden)]
648
    #[cfg(feature = "compiled_data")]
649
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static>;
650
}
651
652
// Abstract over Linear/Sparse/Script representation
653
// This trait is implicitly sealed by not being exported.
654
pub trait PropertyEnumToValueNameLookup {
655
    fn get(&self, prop: u32) -> Option<&str>;
656
}
657
658
impl PropertyEnumToValueNameLookup for PropertyEnumToValueNameLinearMap<'_> {
659
0
    fn get(&self, prop: u32) -> Option<&str> {
660
0
        self.map.get(usize::try_from(prop).ok()?)
661
0
    }
662
}
663
664
#[cfg(feature = "alloc")]
665
impl PropertyEnumToValueNameLookup for PropertyEnumToValueNameSparseMap<'_> {
666
    fn get(&self, prop: u32) -> Option<&str> {
667
        self.map.get(&u16::try_from(prop).ok()?)
668
    }
669
}
670
671
impl PropertyEnumToValueNameLookup for PropertyScriptToIcuScriptMap<'_> {
672
0
    fn get(&self, prop: u32) -> Option<&str> {
673
0
        self.map
674
0
            .get_ule_ref(usize::try_from(prop).ok()?)
675
0
            .and_then(|no| no.as_ref())
676
0
            .map(|s| s.as_str())
677
0
    }
678
}
679
680
/// A property whose value names can be represented as strings.
681
pub trait NamedEnumeratedProperty: ParseableEnumeratedProperty {
682
    #[doc(hidden)]
683
    type DataStructLong: 'static
684
        + for<'a> Yokeable<'a, Output = Self::DataStructLongBorrowed<'a>>
685
        + PropertyEnumToValueNameLookup;
686
    #[doc(hidden)]
687
    type DataStructShort: 'static
688
        + for<'a> Yokeable<'a, Output = Self::DataStructShortBorrowed<'a>>
689
        + PropertyEnumToValueNameLookup;
690
    #[doc(hidden)]
691
    type DataStructLongBorrowed<'a>: PropertyEnumToValueNameLookup;
692
    #[doc(hidden)]
693
    type DataStructShortBorrowed<'a>: PropertyEnumToValueNameLookup;
694
    #[doc(hidden)]
695
    type DataMarkerLong: DataMarker<DataStruct = Self::DataStructLong>;
696
    #[doc(hidden)]
697
    type DataMarkerShort: DataMarker<DataStruct = Self::DataStructShort>;
698
    #[doc(hidden)]
699
    #[cfg(feature = "compiled_data")]
700
    const SINGLETON_LONG: &'static Self::DataStructLongBorrowed<'static>;
701
    #[doc(hidden)]
702
    #[cfg(feature = "compiled_data")]
703
    const SINGLETON_SHORT: &'static Self::DataStructShortBorrowed<'static>;
704
705
    // These wouldn't be necessary if Yoke used GATs (#6057)
706
    #[doc(hidden)]
707
    fn nep_long_identity<'a>(
708
        stat: &'a <Self::DataStructLong as Yokeable<'a>>::Output,
709
    ) -> &'a Self::DataStructLongBorrowed<'a>;
710
    #[doc(hidden)]
711
    fn nep_long_identity_static(
712
        stat: &'static Self::DataStructLongBorrowed<'static>,
713
    ) -> &'static Self::DataStructLong;
714
715
    #[doc(hidden)]
716
    fn nep_short_identity<'a>(
717
        stat: &'a <Self::DataStructShort as Yokeable<'a>>::Output,
718
    ) -> &'a Self::DataStructShortBorrowed<'a>;
719
    #[doc(hidden)]
720
    fn nep_short_identity_static(
721
        stat: &'static Self::DataStructShortBorrowed<'static>,
722
    ) -> &'static Self::DataStructShort;
723
724
    /// Convenience method for `PropertyParser::new().get_loose(s)`
725
    ///
726
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
727
    #[cfg(feature = "compiled_data")]
728
    fn try_from_str(s: &str) -> Option<Self> {
729
        PropertyParser::new().get_loose(s)
730
    }
731
    /// Convenience method for `PropertyNamesLong::new().get(*self).unwrap()`
732
    ///
733
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
734
    #[cfg(feature = "compiled_data")]
735
    fn long_name(&self) -> &'static str {
736
        PropertyNamesLong::new().get(*self).unwrap_or("unreachable")
737
    }
738
    /// Convenience method for `PropertyNamesShort::new().get(*self).unwrap()`
739
    ///
740
    /// ✨ *Enabled with the `compiled_data` Cargo feature.*
741
    #[cfg(feature = "compiled_data")]
742
    fn short_name(&self) -> &'static str {
743
        PropertyNamesShort::new()
744
            .get(*self)
745
            .unwrap_or("unreachable")
746
    }
747
}
748
749
macro_rules! impl_value_getter {
750
    (
751
        impl $ty:ident {
752
            $marker_n2e:ident / $singleton_n2e:ident;
753
            $(
754
                $(#[$meta:meta])*
755
                $data_struct_s:ident / $marker_e2sn:ident / $singleton_e2sn:ident;
756
                $data_struct_l:ident / $marker_e2ln:ident / $singleton_e2ln:ident;
757
            )?
758
        }
759
    ) => {
760
        impl ParseableEnumeratedProperty for $ty {
761
            type DataMarker = $marker_n2e;
762
            #[cfg(feature = "compiled_data")]
763
            const SINGLETON: &'static PropertyValueNameToEnumMap<'static> = crate::provider::Baked::$singleton_n2e;
764
        }
765
766
        $(
767
            $(#[$meta])*
768
            impl NamedEnumeratedProperty for $ty {
769
                type DataStructLong = $data_struct_l<'static>;
770
                type DataStructShort = $data_struct_s<'static>;
771
                type DataStructLongBorrowed<'a> = $data_struct_l<'a>;
772
                type DataStructShortBorrowed<'a> = $data_struct_s<'a>;
773
                type DataMarkerLong = crate::provider::$marker_e2ln;
774
                type DataMarkerShort = crate::provider::$marker_e2sn;
775
                #[cfg(feature = "compiled_data")]
776
                const SINGLETON_LONG: &'static Self::DataStructLong = crate::provider::Baked::$singleton_e2ln;
777
                #[cfg(feature = "compiled_data")]
778
                const SINGLETON_SHORT: &'static Self::DataStructShort = crate::provider::Baked::$singleton_e2sn;
779
0
                fn nep_long_identity<'a>(yoked: &'a $data_struct_l<'a>) -> &'a Self::DataStructLongBorrowed<'a> {
780
0
                    yoked
781
0
                }
Unexecuted instantiation: <icu_properties::props::LineBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::GraphemeClusterBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::WordBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::SentenceBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::IndicSyllabicCategory as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::IndicConjunctBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::JoiningType as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::VerticalOrientation as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::BidiClass as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::Script as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::HangulSyllableType as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::EastAsianWidth as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
Unexecuted instantiation: <icu_properties::props::gc::GeneralCategory as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity
782
783
0
                fn nep_long_identity_static(stat: &'static $data_struct_l<'static>) -> &'static $data_struct_l<'static> {
784
0
                    stat
785
0
                }
Unexecuted instantiation: <icu_properties::props::LineBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::GraphemeClusterBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::WordBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::SentenceBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::IndicSyllabicCategory as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::IndicConjunctBreak as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::JoiningType as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::VerticalOrientation as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::BidiClass as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::Script as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::HangulSyllableType as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::EastAsianWidth as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
Unexecuted instantiation: <icu_properties::props::gc::GeneralCategory as icu_properties::names::NamedEnumeratedProperty>::nep_long_identity_static
786
787
788
0
                fn nep_short_identity<'a>(yoked: &'a $data_struct_s<'a>) -> &'a Self::DataStructShortBorrowed<'a> {
789
0
                    yoked
790
0
                }
Unexecuted instantiation: <icu_properties::props::LineBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::GraphemeClusterBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::WordBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::SentenceBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::IndicSyllabicCategory as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::IndicConjunctBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::JoiningType as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::VerticalOrientation as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::BidiClass as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::Script as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::HangulSyllableType as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::EastAsianWidth as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
Unexecuted instantiation: <icu_properties::props::gc::GeneralCategory as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity
791
0
                fn nep_short_identity_static(stat: &'static $data_struct_s<'static>) -> &'static $data_struct_s<'static> {
792
0
                    stat
793
0
                }
Unexecuted instantiation: <icu_properties::props::LineBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::GraphemeClusterBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::WordBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::SentenceBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::IndicSyllabicCategory as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::IndicConjunctBreak as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::JoiningType as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::VerticalOrientation as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::BidiClass as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::Script as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::HangulSyllableType as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::EastAsianWidth as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
Unexecuted instantiation: <icu_properties::props::gc::GeneralCategory as icu_properties::names::NamedEnumeratedProperty>::nep_short_identity_static
794
795
            }
796
797
798
        )?
799
    };
800
}
801
802
impl_value_getter! {
803
    impl BidiClass {
804
        PropertyNameParseBidiClassV1 / SINGLETON_PROPERTY_NAME_PARSE_BIDI_CLASS_V1;
805
        PropertyEnumToValueNameLinearMap / PropertyNameShortBidiClassV1 / SINGLETON_PROPERTY_NAME_SHORT_BIDI_CLASS_V1;
806
        PropertyEnumToValueNameLinearMap / PropertyNameLongBidiClassV1 / SINGLETON_PROPERTY_NAME_LONG_BIDI_CLASS_V1;
807
    }
808
}
809
810
impl_value_getter! {
811
    impl GeneralCategory {
812
        PropertyNameParseGeneralCategoryV1 / SINGLETON_PROPERTY_NAME_PARSE_GENERAL_CATEGORY_V1;
813
        PropertyEnumToValueNameLinearMap / PropertyNameShortGeneralCategoryV1 / SINGLETON_PROPERTY_NAME_SHORT_GENERAL_CATEGORY_V1;
814
        PropertyEnumToValueNameLinearMap / PropertyNameLongGeneralCategoryV1 / SINGLETON_PROPERTY_NAME_LONG_GENERAL_CATEGORY_V1;
815
    }
816
}
817
818
impl_value_getter! {
819
    impl GeneralCategoryGroup {
820
        PropertyNameParseGeneralCategoryMaskV1 / SINGLETON_PROPERTY_NAME_PARSE_GENERAL_CATEGORY_MASK_V1;
821
    }
822
}
823
824
impl_value_getter! {
825
    impl Script {
826
        PropertyNameParseScriptV1 / SINGLETON_PROPERTY_NAME_PARSE_SCRIPT_V1;
827
        PropertyScriptToIcuScriptMap / PropertyNameShortScriptV1 / SINGLETON_PROPERTY_NAME_SHORT_SCRIPT_V1;
828
        PropertyEnumToValueNameLinearMap / PropertyNameLongScriptV1 / SINGLETON_PROPERTY_NAME_LONG_SCRIPT_V1;
829
    }
830
}
831
832
impl_value_getter! {
833
   impl HangulSyllableType {
834
        PropertyNameParseHangulSyllableTypeV1 / SINGLETON_PROPERTY_NAME_PARSE_HANGUL_SYLLABLE_TYPE_V1;
835
        PropertyEnumToValueNameLinearMap / PropertyNameShortHangulSyllableTypeV1 / SINGLETON_PROPERTY_NAME_SHORT_HANGUL_SYLLABLE_TYPE_V1;
836
        PropertyEnumToValueNameLinearMap / PropertyNameLongHangulSyllableTypeV1 / SINGLETON_PROPERTY_NAME_LONG_HANGUL_SYLLABLE_TYPE_V1;
837
    }
838
}
839
840
impl_value_getter! {
841
    impl EastAsianWidth {
842
        PropertyNameParseEastAsianWidthV1 / SINGLETON_PROPERTY_NAME_PARSE_EAST_ASIAN_WIDTH_V1;
843
        PropertyEnumToValueNameLinearMap / PropertyNameShortEastAsianWidthV1 / SINGLETON_PROPERTY_NAME_SHORT_EAST_ASIAN_WIDTH_V1;
844
        PropertyEnumToValueNameLinearMap / PropertyNameLongEastAsianWidthV1 / SINGLETON_PROPERTY_NAME_LONG_EAST_ASIAN_WIDTH_V1;
845
    }
846
}
847
848
impl_value_getter! {
849
    impl LineBreak {
850
        PropertyNameParseLineBreakV1 / SINGLETON_PROPERTY_NAME_PARSE_LINE_BREAK_V1;
851
        PropertyEnumToValueNameLinearMap / PropertyNameShortLineBreakV1 / SINGLETON_PROPERTY_NAME_SHORT_LINE_BREAK_V1;
852
        PropertyEnumToValueNameLinearMap / PropertyNameLongLineBreakV1 / SINGLETON_PROPERTY_NAME_LONG_LINE_BREAK_V1;
853
    }
854
}
855
856
impl_value_getter! {
857
    impl GraphemeClusterBreak {
858
        PropertyNameParseGraphemeClusterBreakV1 / SINGLETON_PROPERTY_NAME_PARSE_GRAPHEME_CLUSTER_BREAK_V1;
859
        PropertyEnumToValueNameLinearMap / PropertyNameShortGraphemeClusterBreakV1 / SINGLETON_PROPERTY_NAME_SHORT_GRAPHEME_CLUSTER_BREAK_V1;
860
        PropertyEnumToValueNameLinearMap / PropertyNameLongGraphemeClusterBreakV1 / SINGLETON_PROPERTY_NAME_LONG_GRAPHEME_CLUSTER_BREAK_V1;
861
    }
862
}
863
864
impl_value_getter! {
865
    impl WordBreak {
866
        PropertyNameParseWordBreakV1 / SINGLETON_PROPERTY_NAME_PARSE_WORD_BREAK_V1;
867
        PropertyEnumToValueNameLinearMap / PropertyNameShortWordBreakV1 / SINGLETON_PROPERTY_NAME_SHORT_WORD_BREAK_V1;
868
        PropertyEnumToValueNameLinearMap / PropertyNameLongWordBreakV1 / SINGLETON_PROPERTY_NAME_LONG_WORD_BREAK_V1;
869
    }
870
}
871
872
impl_value_getter! {
873
    impl SentenceBreak {
874
        PropertyNameParseSentenceBreakV1 / SINGLETON_PROPERTY_NAME_PARSE_SENTENCE_BREAK_V1;
875
        PropertyEnumToValueNameLinearMap / PropertyNameShortSentenceBreakV1 / SINGLETON_PROPERTY_NAME_SHORT_SENTENCE_BREAK_V1;
876
        PropertyEnumToValueNameLinearMap / PropertyNameLongSentenceBreakV1 / SINGLETON_PROPERTY_NAME_LONG_SENTENCE_BREAK_V1;
877
    }
878
}
879
880
impl_value_getter! {
881
    impl CanonicalCombiningClass {
882
        PropertyNameParseCanonicalCombiningClassV1 / SINGLETON_PROPERTY_NAME_PARSE_CANONICAL_COMBINING_CLASS_V1;
883
        #[cfg(feature = "alloc")]
884
        /// ✨ *Enabled with the `alloc` Cargo feature.*
885
        PropertyEnumToValueNameSparseMap / PropertyNameShortCanonicalCombiningClassV1 / SINGLETON_PROPERTY_NAME_SHORT_CANONICAL_COMBINING_CLASS_V1;
886
        PropertyEnumToValueNameSparseMap / PropertyNameLongCanonicalCombiningClassV1 / SINGLETON_PROPERTY_NAME_LONG_CANONICAL_COMBINING_CLASS_V1;
887
    }
888
}
889
890
impl_value_getter! {
891
    impl IndicSyllabicCategory {
892
        PropertyNameParseIndicSyllabicCategoryV1 / SINGLETON_PROPERTY_NAME_PARSE_INDIC_SYLLABIC_CATEGORY_V1;
893
        PropertyEnumToValueNameLinearMap / PropertyNameShortIndicSyllabicCategoryV1 / SINGLETON_PROPERTY_NAME_SHORT_INDIC_SYLLABIC_CATEGORY_V1;
894
        PropertyEnumToValueNameLinearMap / PropertyNameLongIndicSyllabicCategoryV1 / SINGLETON_PROPERTY_NAME_LONG_INDIC_SYLLABIC_CATEGORY_V1;
895
    }
896
}
897
898
impl_value_getter! {
899
    impl IndicConjunctBreak {
900
        PropertyNameParseIndicConjunctBreakV1 / SINGLETON_PROPERTY_NAME_PARSE_INDIC_CONJUNCT_BREAK_V1;
901
        PropertyEnumToValueNameLinearMap / PropertyNameShortIndicConjunctBreakV1 / SINGLETON_PROPERTY_NAME_SHORT_INDIC_CONJUNCT_BREAK_V1;
902
        PropertyEnumToValueNameLinearMap / PropertyNameLongIndicConjunctBreakV1 / SINGLETON_PROPERTY_NAME_LONG_INDIC_CONJUNCT_BREAK_V1;
903
    }
904
}
905
906
impl_value_getter! {
907
    impl JoiningType {
908
        PropertyNameParseJoiningTypeV1 / SINGLETON_PROPERTY_NAME_PARSE_JOINING_TYPE_V1;
909
        PropertyEnumToValueNameLinearMap / PropertyNameShortJoiningTypeV1 / SINGLETON_PROPERTY_NAME_SHORT_JOINING_TYPE_V1;
910
        PropertyEnumToValueNameLinearMap / PropertyNameLongJoiningTypeV1 / SINGLETON_PROPERTY_NAME_LONG_JOINING_TYPE_V1;
911
    }
912
}
913
914
impl_value_getter! {
915
    impl VerticalOrientation {
916
        PropertyNameParseVerticalOrientationV1 / SINGLETON_PROPERTY_NAME_PARSE_VERTICAL_ORIENTATION_V1;
917
        PropertyEnumToValueNameLinearMap / PropertyNameShortVerticalOrientationV1 / SINGLETON_PROPERTY_NAME_SHORT_VERTICAL_ORIENTATION_V1;
918
        PropertyEnumToValueNameLinearMap / PropertyNameLongVerticalOrientationV1 / SINGLETON_PROPERTY_NAME_LONG_VERTICAL_ORIENTATION_V1;
919
    }
920
}