icu_properties/
names.rs

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
5use crate::props::*;
6use crate::provider::names::*;
7use core::marker::PhantomData;
8use icu_collections::codepointtrie::TrieValue;
9use icu_provider::marker::ErasedMarker;
10use icu_provider::prelude::*;
11use yoke::Yokeable;
12use 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(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for PropertyParser<T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "PropertyParser", "map", &self.map, "markers", &&self.markers)
    }
}Debug)]
61pub 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(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug> ::core::fmt::Debug for
    PropertyParserBorrowed<'a, T> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "PropertyParserBorrowed", "map", &self.map, "markers",
            &&self.markers)
    }
}Debug)]
69pub struct PropertyParserBorrowed<'a, T> {
70    map: &'a PropertyValueNameToEnumMap<'a>,
71    markers: PhantomData<fn() -> T>,
72}
73
74impl<T> Clone for PropertyParserBorrowed<'_, T> {
75    fn clone(&self) -> Self {
76        *self
77    }
78}
79impl<T> Copy for PropertyParserBorrowed<'_, T> {}
80
81impl<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    pub fn new() -> PropertyParserBorrowed<'static, T>
90    where
91        T: ParseableEnumeratedProperty,
92    {
93        PropertyParserBorrowed::new()
94    }
95
96    #[doc = "A version of [`Self::new`] that uses custom data provided by a [`DataProvider`].\n\n[\u{1f4da} Help choosing a constructor](icu_provider::constructors)\n\n<div class=\"stab unstable\">\u{26a0}\u{fe0f} The bounds on <tt>provider</tt> may change over time, including in SemVer minor releases.</div>"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
130impl<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    pub fn get_strict_u16(self, name: &str) -> Option<u16> {
154        get_strict_u16(self.map, name)
155    }
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    pub fn get_strict(self, name: &str) -> Option<T> {
180        T::try_from_u32(self.get_strict_u16(name)? as u32).ok()
181    }
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")]
245impl<T: ParseableEnumeratedProperty> Default for PropertyParserBorrowed<'static, T> {
246    fn default() -> Self {
247        Self::new()
248    }
249}
250
251impl<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    pub fn new() -> Self
259    where
260        T: ParseableEnumeratedProperty,
261    {
262        Self {
263            map: T::SINGLETON,
264            markers: PhantomData,
265        }
266    }
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
281fn get_strict_u16(payload: &PropertyValueNameToEnumMap<'_>, name: &str) -> Option<u16> {
282    payload.map.get(name).and_then(|i| i.try_into().ok())
283}
284
285/// Avoid monomorphizing multiple copies of this function
286fn get_loose_u16(payload: &PropertyValueNameToEnumMap<'_>, name: &str) -> Option<u16> {
287    fn recurse(mut cursor: ZeroTrieSimpleAsciiCursor, mut rest: &[u8]) -> Option<usize> {
288        if cursor.is_empty() {
289            return None;
290        }
291
292        // Skip whitespace, underscore, hyphen in trie.
293        for skip in [b'\t', b'\n', b'\x0C', b'\r', b' ', 0x0B, b'_', b'-'] {
294            let mut skip_cursor = cursor.clone();
295            skip_cursor.step(skip);
296            if let Some(r) = recurse(skip_cursor, rest) {
297                return Some(r);
298            }
299        }
300
301        let ascii = loop {
302            let Some((&a, r)) = rest.split_first() else {
303                return cursor.take_value();
304            };
305            rest = r;
306
307            // Skip whitespace, underscore, hyphen in input
308            if !#[allow(non_exhaustive_omitted_patterns)] match a {
    b'\t' | b'\n' | b'\x0C' | b'\r' | b' ' | 0x0B | b'_' | b'-' => true,
    _ => false,
}matches!(
309                a,
310                b'\t' | b'\n' | b'\x0C' | b'\r' | b' ' | 0x0B | b'_' | b'-'
311            ) {
312                break a;
313            }
314        };
315
316        let mut other_case_cursor = cursor.clone();
317        cursor.step(ascii);
318        other_case_cursor.step(if ascii.is_ascii_lowercase() {
319            ascii.to_ascii_uppercase()
320        } else {
321            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        recurse(cursor, rest).or_else(|| recurse(other_case_cursor, rest))
327    }
328
329    recurse(payload.map.cursor(), name.as_bytes()).and_then(|i| i.try_into().ok())
330}
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/// ```
352pub struct PropertyNamesLong<T: NamedEnumeratedProperty> {
353    map: DataPayload<ErasedMarker<T::DataStructLong>>,
354}
355
356impl<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(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug + NamedEnumeratedProperty> ::core::fmt::Debug
    for PropertyNamesLongBorrowed<'a, T> where
    T::DataStructLongBorrowed<'a>: ::core::fmt::Debug {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "PropertyNamesLongBorrowed", "map", &&self.map)
    }
}Debug)]
367pub struct PropertyNamesLongBorrowed<'a, T: NamedEnumeratedProperty> {
368    map: &'a T::DataStructLongBorrowed<'a>,
369}
370
371impl<T: NamedEnumeratedProperty> Clone for PropertyNamesLongBorrowed<'_, T> {
372    fn clone(&self) -> Self {
373        *self
374    }
375}
376impl<T: NamedEnumeratedProperty> Copy for PropertyNamesLongBorrowed<'_, T> {}
377
378impl<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 = "A version of [`Self::new`] that uses custom data provided by a [`DataProvider`].\n\n[\u{1f4da} Help choosing a constructor](icu_provider::constructors)\n\n<div class=\"stab unstable\">\u{26a0}\u{fe0f} The bounds on <tt>provider</tt> may change over time, including in SemVer minor releases.</div>"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
411impl<'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")]
437impl<T: NamedEnumeratedProperty> Default for PropertyNamesLongBorrowed<'static, T> {
438    fn default() -> Self {
439        Self::new()
440    }
441}
442
443impl<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/// ```
484pub struct PropertyNamesShort<T: NamedEnumeratedProperty> {
485    map: DataPayload<ErasedMarker<T::DataStructShort>>,
486}
487
488impl<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(#[automatically_derived]
impl<'a, T: ::core::fmt::Debug + NamedEnumeratedProperty> ::core::fmt::Debug
    for PropertyNamesShortBorrowed<'a, T> where
    T::DataStructShortBorrowed<'a>: ::core::fmt::Debug {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "PropertyNamesShortBorrowed", "map", &&self.map)
    }
}Debug)]
499pub struct PropertyNamesShortBorrowed<'a, T: NamedEnumeratedProperty> {
500    map: &'a T::DataStructShortBorrowed<'a>,
501}
502
503impl<T: NamedEnumeratedProperty> Clone for PropertyNamesShortBorrowed<'_, T> {
504    fn clone(&self) -> Self {
505        *self
506    }
507}
508
509impl<T: NamedEnumeratedProperty> Copy for PropertyNamesShortBorrowed<'_, T> {}
510
511impl<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    pub fn new() -> PropertyNamesShortBorrowed<'static, T> {
520        PropertyNamesShortBorrowed::new()
521    }
522
523    #[doc = "A version of [`Self::new`] that uses custom data provided by a [`DataProvider`].\n\n[\u{1f4da} Help choosing a constructor](icu_provider::constructors)\n\n<div class=\"stab unstable\">\u{26a0}\u{fe0f} The bounds on <tt>provider</tt> may change over time, including in SemVer minor releases.</div>"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
544impl<'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
563impl 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    pub fn get_locale_script(self, property: Script) -> Option<icu_locale_core::subtags::Script> {
604        let prop = usize::try_from(property.to_u32()).ok()?;
605        self.map.map.get(prop).and_then(|o| o.0)
606    }
607}
608
609#[cfg(feature = "compiled_data")]
610impl<T: NamedEnumeratedProperty> Default for PropertyNamesShortBorrowed<'static, T> {
611    fn default() -> Self {
612        Self::new()
613    }
614}
615
616impl<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    pub fn new() -> Self {
624        Self {
625            map: T::SINGLETON_SHORT,
626        }
627    }
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.
644pub 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.
654pub trait PropertyEnumToValueNameLookup {
655    fn get(&self, prop: u32) -> Option<&str>;
656}
657
658impl PropertyEnumToValueNameLookup for PropertyEnumToValueNameLinearMap<'_> {
659    fn get(&self, prop: u32) -> Option<&str> {
660        self.map.get(usize::try_from(prop).ok()?)
661    }
662}
663
664#[cfg(feature = "alloc")]
665impl PropertyEnumToValueNameLookup for PropertyEnumToValueNameSparseMap<'_> {
666    fn get(&self, prop: u32) -> Option<&str> {
667        self.map.get(&u16::try_from(prop).ok()?)
668    }
669}
670
671impl PropertyEnumToValueNameLookup for PropertyScriptToIcuScriptMap<'_> {
672    fn get(&self, prop: u32) -> Option<&str> {
673        self.map
674            .get_ule_ref(usize::try_from(prop).ok()?)
675            .and_then(|no| no.as_ref())
676            .map(|s| s.as_str())
677    }
678}
679
680/// A property whose value names can be represented as strings.
681pub 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
749macro_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                fn nep_long_identity<'a>(yoked: &'a $data_struct_l<'a>) -> &'a Self::DataStructLongBorrowed<'a> {
780                    yoked
781                }
782
783                fn nep_long_identity_static(stat: &'static $data_struct_l<'static>) -> &'static $data_struct_l<'static> {
784                    stat
785                }
786
787
788                fn nep_short_identity<'a>(yoked: &'a $data_struct_s<'a>) -> &'a Self::DataStructShortBorrowed<'a> {
789                    yoked
790                }
791                fn nep_short_identity_static(stat: &'static $data_struct_s<'static>) -> &'static $data_struct_s<'static> {
792                    stat
793                }
794
795            }
796
797
798        )?
799    };
800}
801
802impl ParseableEnumeratedProperty for BidiClass {
    type DataMarker = PropertyNameParseBidiClassV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_BIDI_CLASS_V1;
}
impl NamedEnumeratedProperty for BidiClass {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongBidiClassV1;
    type DataMarkerShort = crate::provider::PropertyNameShortBidiClassV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_BIDI_CLASS_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_BIDI_CLASS_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
810impl ParseableEnumeratedProperty for GeneralCategory {
    type DataMarker = PropertyNameParseGeneralCategoryV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_GENERAL_CATEGORY_V1;
}
impl NamedEnumeratedProperty for GeneralCategory {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongGeneralCategoryV1;
    type DataMarkerShort =
        crate::provider::PropertyNameShortGeneralCategoryV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_GENERAL_CATEGORY_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_GENERAL_CATEGORY_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
818impl ParseableEnumeratedProperty for GeneralCategoryGroup {
    type DataMarker = PropertyNameParseGeneralCategoryMaskV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_GENERAL_CATEGORY_MASK_V1;
}impl_value_getter! {
819    impl GeneralCategoryGroup {
820        PropertyNameParseGeneralCategoryMaskV1 / SINGLETON_PROPERTY_NAME_PARSE_GENERAL_CATEGORY_MASK_V1;
821    }
822}
823
824impl ParseableEnumeratedProperty for Script {
    type DataMarker = PropertyNameParseScriptV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_SCRIPT_V1;
}
impl NamedEnumeratedProperty for Script {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyScriptToIcuScriptMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyScriptToIcuScriptMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongScriptV1;
    type DataMarkerShort = crate::provider::PropertyNameShortScriptV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_SCRIPT_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_SCRIPT_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyScriptToIcuScriptMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyScriptToIcuScriptMap<'static>)
        -> &'static PropertyScriptToIcuScriptMap<'static> {
        stat
    }
}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
832impl ParseableEnumeratedProperty for HangulSyllableType {
    type DataMarker = PropertyNameParseHangulSyllableTypeV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_HANGUL_SYLLABLE_TYPE_V1;
}
impl NamedEnumeratedProperty for HangulSyllableType {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong =
        crate::provider::PropertyNameLongHangulSyllableTypeV1;
    type DataMarkerShort =
        crate::provider::PropertyNameShortHangulSyllableTypeV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_HANGUL_SYLLABLE_TYPE_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_HANGUL_SYLLABLE_TYPE_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
840impl ParseableEnumeratedProperty for EastAsianWidth {
    type DataMarker = PropertyNameParseEastAsianWidthV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_EAST_ASIAN_WIDTH_V1;
}
impl NamedEnumeratedProperty for EastAsianWidth {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongEastAsianWidthV1;
    type DataMarkerShort = crate::provider::PropertyNameShortEastAsianWidthV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_EAST_ASIAN_WIDTH_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_EAST_ASIAN_WIDTH_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
848impl ParseableEnumeratedProperty for LineBreak {
    type DataMarker = PropertyNameParseLineBreakV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_LINE_BREAK_V1;
}
impl NamedEnumeratedProperty for LineBreak {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongLineBreakV1;
    type DataMarkerShort = crate::provider::PropertyNameShortLineBreakV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_LINE_BREAK_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_LINE_BREAK_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
856impl ParseableEnumeratedProperty for GraphemeClusterBreak {
    type DataMarker = PropertyNameParseGraphemeClusterBreakV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_GRAPHEME_CLUSTER_BREAK_V1;
}
impl NamedEnumeratedProperty for GraphemeClusterBreak {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong =
        crate::provider::PropertyNameLongGraphemeClusterBreakV1;
    type DataMarkerShort =
        crate::provider::PropertyNameShortGraphemeClusterBreakV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_GRAPHEME_CLUSTER_BREAK_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_GRAPHEME_CLUSTER_BREAK_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
864impl ParseableEnumeratedProperty for WordBreak {
    type DataMarker = PropertyNameParseWordBreakV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_WORD_BREAK_V1;
}
impl NamedEnumeratedProperty for WordBreak {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongWordBreakV1;
    type DataMarkerShort = crate::provider::PropertyNameShortWordBreakV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_WORD_BREAK_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_WORD_BREAK_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
872impl ParseableEnumeratedProperty for SentenceBreak {
    type DataMarker = PropertyNameParseSentenceBreakV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_SENTENCE_BREAK_V1;
}
impl NamedEnumeratedProperty for SentenceBreak {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongSentenceBreakV1;
    type DataMarkerShort = crate::provider::PropertyNameShortSentenceBreakV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_SENTENCE_BREAK_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_SENTENCE_BREAK_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
880impl ParseableEnumeratedProperty for CanonicalCombiningClass {
    type DataMarker = PropertyNameParseCanonicalCombiningClassV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_CANONICAL_COMBINING_CLASS_V1;
}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
890impl ParseableEnumeratedProperty for IndicSyllabicCategory {
    type DataMarker = PropertyNameParseIndicSyllabicCategoryV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_INDIC_SYLLABIC_CATEGORY_V1;
}
impl NamedEnumeratedProperty for IndicSyllabicCategory {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong =
        crate::provider::PropertyNameLongIndicSyllabicCategoryV1;
    type DataMarkerShort =
        crate::provider::PropertyNameShortIndicSyllabicCategoryV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_INDIC_SYLLABIC_CATEGORY_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_INDIC_SYLLABIC_CATEGORY_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}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
898impl ParseableEnumeratedProperty for JoiningType {
    type DataMarker = PropertyNameParseJoiningTypeV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_JOINING_TYPE_V1;
}
impl NamedEnumeratedProperty for JoiningType {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong = crate::provider::PropertyNameLongJoiningTypeV1;
    type DataMarkerShort = crate::provider::PropertyNameShortJoiningTypeV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_JOINING_TYPE_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_JOINING_TYPE_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}impl_value_getter! {
899    impl JoiningType {
900        PropertyNameParseJoiningTypeV1 / SINGLETON_PROPERTY_NAME_PARSE_JOINING_TYPE_V1;
901        PropertyEnumToValueNameLinearMap / PropertyNameShortJoiningTypeV1 / SINGLETON_PROPERTY_NAME_SHORT_JOINING_TYPE_V1;
902        PropertyEnumToValueNameLinearMap / PropertyNameLongJoiningTypeV1 / SINGLETON_PROPERTY_NAME_LONG_JOINING_TYPE_V1;
903    }
904}
905
906impl ParseableEnumeratedProperty for VerticalOrientation {
    type DataMarker = PropertyNameParseVerticalOrientationV1;
    const SINGLETON: &'static PropertyValueNameToEnumMap<'static> =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_PARSE_VERTICAL_ORIENTATION_V1;
}
impl NamedEnumeratedProperty for VerticalOrientation {
    type DataStructLong = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructShort = PropertyEnumToValueNameLinearMap<'static>;
    type DataStructLongBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataStructShortBorrowed<'a> = PropertyEnumToValueNameLinearMap<'a>;
    type DataMarkerLong =
        crate::provider::PropertyNameLongVerticalOrientationV1;
    type DataMarkerShort =
        crate::provider::PropertyNameShortVerticalOrientationV1;
    const SINGLETON_LONG: &'static Self::DataStructLong =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_LONG_VERTICAL_ORIENTATION_V1;
    const SINGLETON_SHORT: &'static Self::DataStructShort =
        crate::provider::Baked::SINGLETON_PROPERTY_NAME_SHORT_VERTICAL_ORIENTATION_V1;
    fn nep_long_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructLongBorrowed<'a> {
        yoked
    }
    fn nep_long_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
    fn nep_short_identity<'a>(yoked: &'a PropertyEnumToValueNameLinearMap<'a>)
        -> &'a Self::DataStructShortBorrowed<'a> {
        yoked
    }
    fn nep_short_identity_static(stat:
            &'static PropertyEnumToValueNameLinearMap<'static>)
        -> &'static PropertyEnumToValueNameLinearMap<'static> {
        stat
    }
}impl_value_getter! {
907    impl VerticalOrientation {
908        PropertyNameParseVerticalOrientationV1 / SINGLETON_PROPERTY_NAME_PARSE_VERTICAL_ORIENTATION_V1;
909        PropertyEnumToValueNameLinearMap / PropertyNameShortVerticalOrientationV1 / SINGLETON_PROPERTY_NAME_SHORT_VERTICAL_ORIENTATION_V1;
910        PropertyEnumToValueNameLinearMap / PropertyNameLongVerticalOrientationV1 / SINGLETON_PROPERTY_NAME_LONG_VERTICAL_ORIENTATION_V1;
911    }
912}