usecrate::props::*; usecrate::provider::names::*; use core::marker::PhantomData; use icu_collections::codepointtrie::TrieValue; use icu_provider::marker::ErasedMarker; use icu_provider::prelude::*; use yoke::Yokeable; use zerotrie::cursor::ZeroTrieSimpleAsciiCursor;
/// A struct capable of looking up a property value from a string name. /// Access its data by calling [`Self::as_borrowed()`] and using the methods on /// [`PropertyParserBorrowed`]. /// /// The name can be a short name (`Lu`), a long name(`Uppercase_Letter`), /// or an alias. /// /// Property names can be looked up using "strict" matching (looking for a name /// that matches exactly), or "loose matching", where the name is allowed to deviate /// in terms of ASCII casing, whitespace, underscores, and hyphens. /// /// # Example /// /// ``` /// use icu::properties::props::GeneralCategory; /// use icu::properties::PropertyParser; /// /// let lookup = PropertyParser::<GeneralCategory>::new(); /// // short name for value /// assert_eq!( /// lookup.get_strict("Lu"), /// Some(GeneralCategory::UppercaseLetter) /// ); /// assert_eq!( /// lookup.get_strict("Pd"), /// Some(GeneralCategory::DashPunctuation) /// ); /// // long name for value /// assert_eq!( /// lookup.get_strict("Uppercase_Letter"), /// Some(GeneralCategory::UppercaseLetter) /// ); /// assert_eq!( /// lookup.get_strict("Dash_Punctuation"), /// Some(GeneralCategory::DashPunctuation) /// ); /// // name has incorrect casing /// assert_eq!(lookup.get_strict("dashpunctuation"), None); /// // loose matching of name /// assert_eq!( /// lookup.get_loose("dash-punctuation"), /// Some(GeneralCategory::DashPunctuation) /// ); /// // fake property /// assert_eq!(lookup.get_strict("Animated_Gif"), None); /// ``` #[derive(Debug)] pubstruct PropertyParser<T> {
map: DataPayload<ErasedMarker<PropertyValueNameToEnumMap<'static>>>,
markers: PhantomData<fn() -> T>,
}
/// A borrowed wrapper around property value name-to-enum data, returned by /// [`PropertyParser::as_borrowed()`]. More efficient to query. #[derive(Debug)] pubstruct PropertyParserBorrowed<'a, T> {
map: &'a PropertyValueNameToEnumMap<'a>,
markers: PhantomData<fn() -> T>,
}
impl<T> Clone for PropertyParserBorrowed<'_, T> { fn clone(&self) -> Self {
*self
}
} impl<T> Copy for PropertyParserBorrowed<'_, T> {}
impl<T> PropertyParser<T> { /// Creates a new instance of `PropertyParser<T>` using compiled data. /// /// ✨ *Enabled with the `compiled_data` Cargo feature.* /// /// [ Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] #[expect(clippy::new_ret_no_self)] pubconstfn new() -> PropertyParserBorrowed<'static, T> where
T: ParseableEnumeratedProperty,
{
PropertyParserBorrowed::new()
}
/// Construct a borrowed version of this type that can be queried. /// /// This avoids a potential small underlying cost per API call (like `get_strict()`) by consolidating it /// up front. #[inline] pubfn as_borrowed(&self) -> PropertyParserBorrowed<'_, T> {
PropertyParserBorrowed {
map: self.map.get(),
markers: PhantomData,
}
}
#[doc(hidden)] // used by FFI code pubfn erase(self) -> PropertyParser<u16> {
PropertyParser {
map: self.map.cast(),
markers: PhantomData,
}
}
}
impl<T: TrieValue> PropertyParserBorrowed<'_, T> { /// Get the property value as a u16, doing a strict search looking for /// names that match exactly /// /// # Example /// /// ``` /// use icu::properties::props::GeneralCategory; /// use icu::properties::PropertyParser; /// /// let lookup = PropertyParser::<GeneralCategory>::new(); /// assert_eq!( /// lookup.get_strict_u16("Lu"), /// Some(GeneralCategory::UppercaseLetter as u16) /// ); /// assert_eq!( /// lookup.get_strict_u16("Uppercase_Letter"), /// Some(GeneralCategory::UppercaseLetter as u16) /// ); /// // does not do loose matching /// assert_eq!(lookup.get_strict_u16("UppercaseLetter"), None); /// ``` #[inline] pubfn get_strict_u16(self, name: &str) -> Option<u16> { self.get_strict_u16_utf8(name.as_bytes())
}
/// Get the property value as a `T`, doing a strict search looking for /// names that match exactly /// /// # Example /// /// ``` /// use icu::properties::props::GeneralCategory; /// use icu::properties::PropertyParser; /// /// let lookup = PropertyParser::<GeneralCategory>::new(); /// assert_eq!( /// lookup.get_strict("Lu"), /// Some(GeneralCategory::UppercaseLetter) /// ); /// assert_eq!( /// lookup.get_strict("Uppercase_Letter"), /// Some(GeneralCategory::UppercaseLetter) /// ); /// // does not do loose matching /// assert_eq!(lookup.get_strict("UppercaseLetter"), None); /// ``` #[inline] pubfn get_strict(self, name: &str) -> Option<T> { self.get_strict_utf8(name.as_bytes())
}
/// Get the property value as a u16, doing a loose search looking for /// names that match case-insensitively, ignoring ASCII hyphens, underscores, and /// whitespaces. /// /// # Example /// /// ``` /// use icu::properties::props::GeneralCategory; /// use icu::properties::PropertyParser; /// /// let lookup = PropertyParser::<GeneralCategory>::new(); /// assert_eq!( /// lookup.get_loose_u16("Lu"), /// Some(GeneralCategory::UppercaseLetter as u16) /// ); /// assert_eq!( /// lookup.get_loose_u16("Uppercase_Letter"), /// Some(GeneralCategory::UppercaseLetter as u16) /// ); /// // does do loose matching /// assert_eq!( /// lookup.get_loose_u16("UppercaseLetter"), /// Some(GeneralCategory::UppercaseLetter as u16) /// ); /// ``` #[inline] pubfn get_loose_u16(self, name: &str) -> Option<u16> { self.get_loose_u16_utf8(name.as_bytes())
}
impl<T: TrieValue> PropertyParserBorrowed<'static, T> { /// Creates a new instance of `PropertyParserBorrowed<T>` using compiled data. /// /// ✨ *Enabled with the `compiled_data` Cargo feature.* /// /// [ Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pubconstfn new() -> Self where
T: ParseableEnumeratedProperty,
{ Self {
map: T::SINGLETON,
markers: PhantomData,
}
}
/// Cheaply converts a [`PropertyParserBorrowed<'static>`] into a [`PropertyParser`]. /// /// Note: Due to branching and indirection, using [`PropertyParser`] might inhibit some /// compile-time optimizations that are possible with [`PropertyParserBorrowed`]. pubconstfn static_to_owned(self) -> PropertyParser<T> {
PropertyParser {
map: DataPayload::from_static_ref(self.map),
markers: PhantomData,
}
}
}
/// Avoid monomorphizing multiple copies of this function fn get_strict_u16(payload: &PropertyValueNameToEnumMap<'_>, name: &[u8]) -> Option<u16> {
payload.map.get(name).and_then(|i| i.try_into().ok())
}
/// Avoid monomorphizing multiple copies of this function fn get_loose_u16(payload: &PropertyValueNameToEnumMap<'_>, name: &[u8]) -> Option<u16> { fn recurse(mut cursor: ZeroTrieSimpleAsciiCursor, mut rest: &[u8]) -> Option<usize> { if cursor.is_empty() { return None;
}
// Skip whitespace, underscore, hyphen in trie. for skip in [b'\t', b'\n', b'\x0C', b'\r', b' ', 0x0B, b'_', b'-'] { letmut skip_cursor = cursor.clone();
skip_cursor.step(skip); iflet Some(r) = recurse(skip_cursor, rest) { return Some(r);
}
}
let ascii = loop { let Some((&a, r)) = rest.split_first() else { return cursor.take_value();
};
rest = r;
// Skip whitespace, underscore, hyphen in input if !matches!(
a,
b'\t' | b'\n' | b'\x0C' | b'\r' | b' ' | 0x0B | b'_' | b'-'
) { break a;
}
};
letmut other_case_cursor = cursor.clone();
cursor.step(ascii);
other_case_cursor.step(if ascii.is_ascii_lowercase() {
ascii.to_ascii_uppercase()
} else {
ascii.to_ascii_lowercase()
}); // This uses the call stack as the DFS stack. The recursion will terminate as // rest's length is strictly shrinking. The call stack's depth is limited by // name.len().
recurse(cursor, rest).or_else(|| recurse(other_case_cursor, rest))
}
/// A struct capable of looking up a property name from a value /// Access its data by calling [`Self::as_borrowed()`] and using the methods on /// [`PropertyNamesLongBorrowed`]. /// /// # Example /// /// ``` /// use icu::properties::props::CanonicalCombiningClass; /// use icu::properties::PropertyNamesLong; /// /// let names = PropertyNamesLong::<CanonicalCombiningClass>::new(); /// assert_eq!( /// names.get(CanonicalCombiningClass::KanaVoicing), /// Some("Kana_Voicing") /// ); /// assert_eq!( /// names.get(CanonicalCombiningClass::AboveLeft), /// Some("Above_Left") /// ); /// ``` pubstruct PropertyNamesLong<T: NamedEnumeratedProperty> {
map: DataPayload<ErasedMarker<T::DataStructLong>>,
}
/// A borrowed wrapper around property value name-to-enum data, returned by /// [`PropertyNamesLong::as_borrowed()`]. More efficient to query. #[derive(Debug)] pubstruct PropertyNamesLongBorrowed<'a, T: NamedEnumeratedProperty> {
map: &'a T::DataStructLongBorrowed<'a>,
}
/// Construct a borrowed version of this type that can be queried. /// /// This avoids a potential small underlying cost per API call (like `get_static()`) by consolidating it /// up front. #[inline] pubfn as_borrowed(&self) -> PropertyNamesLongBorrowed<'_, T> {
PropertyNamesLongBorrowed {
map: T::nep_long_identity(self.map.get()),
}
}
}
impl<'a, T: NamedEnumeratedProperty> PropertyNamesLongBorrowed<'a, T> { /// Get the property name given a value /// /// # Example /// /// ```rust /// use icu::properties::props::CanonicalCombiningClass; /// use icu::properties::PropertyNamesLong; /// /// let lookup = PropertyNamesLong::<CanonicalCombiningClass>::new(); /// assert_eq!( /// lookup.get(CanonicalCombiningClass::KanaVoicing), /// Some("Kana_Voicing") /// ); /// assert_eq!( /// lookup.get(CanonicalCombiningClass::AboveLeft), /// Some("Above_Left") /// ); /// ``` #[inline] pubfn get(self, property: T) -> Option<&'a str> { self.map.get(property.to_u32())
}
}
impl<T: NamedEnumeratedProperty> PropertyNamesLongBorrowed<'static, T> { /// Creates a new instance of `PropertyNamesLongBorrowed<T>`. /// /// ✨ *Enabled with the `compiled_data` Cargo feature.* /// /// [ Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pubconstfn new() -> Self { Self {
map: T::SINGLETON_LONG,
}
}
/// Cheaply converts a [`PropertyNamesLongBorrowed<'static>`] into a [`PropertyNamesLong`]. /// /// Note: Due to branching and indirection, using [`PropertyNamesLong`] might inhibit some /// compile-time optimizations that are possible with [`PropertyNamesLongBorrowed`]. /// /// This is currently not `const` unlike other `static_to_owned()` functions since it needs /// const traits to do that safely pubfn static_to_owned(self) -> PropertyNamesLong<T> {
PropertyNamesLong {
map: DataPayload::from_static_ref(T::nep_long_identity_static(self.map)),
}
}
}
/// A struct capable of looking up a property name from a value /// Access its data by calling [`Self::as_borrowed()`] and using the methods on /// [`PropertyNamesShortBorrowed`]. /// /// # Example /// /// ``` /// use icu::properties::props::CanonicalCombiningClass; /// use icu::properties::PropertyNamesShort; /// /// let names = PropertyNamesShort::<CanonicalCombiningClass>::new(); /// assert_eq!(names.get(CanonicalCombiningClass::KanaVoicing), Some("KV")); /// assert_eq!(names.get(CanonicalCombiningClass::AboveLeft), Some("AL")); /// ``` pubstruct PropertyNamesShort<T: NamedEnumeratedProperty> {
map: DataPayload<ErasedMarker<T::DataStructShort>>,
}
/// A borrowed wrapper around property value name-to-enum data, returned by /// [`PropertyNamesShort::as_borrowed()`]. More efficient to query. #[derive(Debug)] pubstruct PropertyNamesShortBorrowed<'a, T: NamedEnumeratedProperty> {
map: &'a T::DataStructShortBorrowed<'a>,
}
/// Construct a borrowed version of this type that can be queried. /// /// This avoids a potential small underlying cost per API call (like `get_static()`) by consolidating it /// up front. #[inline] pubfn as_borrowed(&self) -> PropertyNamesShortBorrowed<'_, T> {
PropertyNamesShortBorrowed {
map: T::nep_short_identity(self.map.get()),
}
}
}
impl<'a, T: NamedEnumeratedProperty> PropertyNamesShortBorrowed<'a, T> { /// Get the property name given a value /// /// # Example /// /// ```rust /// use icu::properties::props::CanonicalCombiningClass; /// use icu::properties::PropertyNamesShort; /// /// let lookup = PropertyNamesShort::<CanonicalCombiningClass>::new(); /// assert_eq!(lookup.get(CanonicalCombiningClass::KanaVoicing), Some("KV")); /// assert_eq!(lookup.get(CanonicalCombiningClass::AboveLeft), Some("AL")); /// ``` #[inline] pubfn get(self, property: T) -> Option<&'a str> { self.map.get(property.to_u32())
}
}
impl PropertyNamesShortBorrowed<'_, Script> { /// Gets the "name" of a script property as a `icu::locale::subtags::Script`. /// /// This method is available only on `PropertyNamesShortBorrowed<Script>`. /// /// # Example /// /// ```rust /// use icu::locale::subtags::script; /// use icu::properties::props::Script; /// use icu::properties::PropertyNamesShort; /// /// let lookup = PropertyNamesShort::<Script>::new(); /// assert_eq!( /// lookup.get_locale_script(Script::Brahmi), /// Some(script!("Brah")) /// ); /// assert_eq!( /// lookup.get_locale_script(Script::Hangul), /// Some(script!("Hang")) /// ); /// ``` /// /// For the reverse direction, use property parsing as normal: /// ``` /// use icu::locale::subtags::script; /// use icu::properties::props::Script; /// use icu::properties::PropertyParser; /// /// let parser = PropertyParser::<Script>::new(); /// assert_eq!( /// parser.get_strict(script!("Brah").as_str()), /// Some(Script::Brahmi) /// ); /// assert_eq!( /// parser.get_strict(script!("Hang").as_str()), /// Some(Script::Hangul) /// ); /// ``` #[inline] pubfn get_locale_script(self, property: Script) -> Option<icu_locale_core::subtags::Script> { let prop = usize::try_from(property.to_u32()).ok()?; self.map.map.get(prop).and_then(|o| o.0)
}
}
impl<T: NamedEnumeratedProperty> PropertyNamesShortBorrowed<'static, T> { /// Creates a new instance of `PropertyNamesShortBorrowed<T>`. /// /// ✨ *Enabled with the `compiled_data` Cargo feature.* /// /// [ Help choosing a constructor](icu_provider::constructors) #[cfg(feature = "compiled_data")] pubconstfn new() -> Self { Self {
map: T::SINGLETON_SHORT,
}
}
/// Cheaply converts a [`PropertyNamesShortBorrowed<'static>`] into a [`PropertyNamesShort`]. /// /// Note: Due to branching and indirection, using [`PropertyNamesShort`] might inhibit some /// compile-time optimizations that are possible with [`PropertyNamesShortBorrowed`]. /// /// This is currently not `const` unlike other `static_to_owned()` functions since it needs /// const traits to do that safely pubfn static_to_owned(self) -> PropertyNamesShort<T> {
PropertyNamesShort {
map: DataPayload::from_static_ref(T::nep_short_identity_static(self.map)),
}
}
}
/// A property whose value names can be parsed from strings. pubtrait ParseableEnumeratedProperty: crate::private::Sealed + TrieValue { #[doc(hidden)] type DataMarker: DataMarker<DataStruct = PropertyValueNameToEnumMap<'static>>; #[doc(hidden)] #[cfg(feature = "compiled_data")] const SINGLETON: &'static PropertyValueNameToEnumMap<'static>;
}
// Abstract over Linear/Sparse/Script representation // This trait is implicitly sealed by not being exported. pubtrait PropertyEnumToValueNameLookup { fn get(&self, prop: u32) -> Option<&str>;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.