icu_locale_core/extensions/transform/
key.rs1#[repr(transparent)]
#[doc = r" A key used in a list of [`Fields`](super::Fields)."]
#[doc = r""]
#[doc = r" The key has to be a two ASCII characters long, with the first"]
#[doc = r" character being alphabetic, and the second being a number."]
#[doc = r""]
#[doc = r" # Examples"]
#[doc = r""]
#[doc = r" ```"]
#[doc = r" use icu::locale::extensions::transform::Key;"]
#[doc = r""]
#[doc = r#" let key1: Key = "k0".parse().expect("Failed to parse a Key.");"#]
#[doc = r""]
#[doc = r#" assert_eq!(key1.as_str(), "k0");"#]
#[doc = r" ```"]
pub struct Key(tinystr::TinyAsciiStr<2>);
#[automatically_derived]
impl ::core::fmt::Debug for Key {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Key", &&self.0)
}
}
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for Key { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Key {
#[inline]
fn eq(&self, other: &Key) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::Eq for Key {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<tinystr::TinyAsciiStr<2>>;
}
}
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Key { }
#[automatically_derived]
impl ::core::clone::Clone for Key {
#[inline]
fn clone(&self) -> Key {
let _: ::core::clone::AssertParamIsClone<tinystr::TinyAsciiStr<2>>;
*self
}
}
#[automatically_derived]
impl ::core::hash::Hash for Key {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for Key {
#[inline]
fn partial_cmp(&self, other: &Key)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}
#[automatically_derived]
impl ::core::cmp::Ord for Key {
#[inline]
fn cmp(&self, other: &Key) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}
#[automatically_derived]
impl ::core::marker::Copy for Key { }
impl Key {
#[doc = "produces a well-formed [`Key`]."]
#[doc = "use icu_locale_core::extensions :: transform ::Key;"]
#[doc = "assert!(Key::try_from_str(\"k0\").is_ok());"]
#[doc = "assert!(Key::try_from_str(\"\").is_err());"]
#[inline]
pub const fn try_from_str(s: &str)
-> Result<Self, crate::parser::errors::ParseError> {
Self::try_from_utf8(s.as_bytes())
}
pub const fn try_from_utf8(code_units: &[u8])
-> Result<Self, crate::parser::errors::ParseError> {
if code_units.len() < 2 || code_units.len() > 2 {
return Err(crate::parser::errors::ParseError::InvalidExtension);
}
match tinystr::TinyAsciiStr::try_from_utf8(code_units) {
Ok(s) if
s.all_bytes()[0].is_ascii_alphabetic() &&
s.all_bytes()[1].is_ascii_digit() =>
Ok(Self(s.to_ascii_lowercase())),
_ => Err(crate::parser::errors::ParseError::InvalidExtension),
}
}
#[doc = "Safely creates a [`Key`] from its raw format"]
pub const fn try_from_raw(raw: [u8; 2])
-> Result<Self, crate::parser::errors::ParseError> {
if let Ok(s) = tinystr::TinyAsciiStr::<2>::try_from_raw(raw) {
if s.len() >= 2 &&
(s.all_bytes()[0].is_ascii_lowercase() &&
s.all_bytes()[1].is_ascii_digit()) {
Ok(Self(s))
} else {
Err(crate::parser::errors::ParseError::InvalidExtension)
}
} else { Err(crate::parser::errors::ParseError::InvalidExtension) }
}
#[doc = "Unsafely creates a [`Key`] from its raw format"]
pub const unsafe fn from_raw_unchecked(v: [u8; 2]) -> Self {
unsafe { Self(tinystr::TinyAsciiStr::from_utf8_unchecked(v)) }
}
pub const fn into_raw(self) -> [u8; 2] { *self.0.all_bytes() }
#[inline]
pub const fn as_str(&self) -> &str { self.0.as_str() }
#[doc(hidden)]
pub const fn to_tinystr(&self) -> tinystr::TinyAsciiStr<2> { self.0 }
#[inline]
pub fn strict_cmp(self, other: &[u8]) -> core::cmp::Ordering {
self.as_str().as_bytes().cmp(other)
}
#[inline]
pub fn normalizing_eq(self, other: &str) -> bool {
self.as_str().eq_ignore_ascii_case(other)
}
}
impl core::str::FromStr for Key {
type Err = crate::parser::errors::ParseError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> { Self::try_from_str(s) }
}
impl<'l> From<&'l Key> for &'l str {
fn from(input: &'l Key) -> Self { input.as_str() }
}
impl From<Key> for tinystr::TinyAsciiStr<2> {
fn from(input: Key) -> Self { input.to_tinystr() }
}
impl ::writeable::Writeable for Key {
#[inline]
fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W)
-> core::fmt::Result {
(self.as_str()).write_to(sink)
}
#[inline]
fn write_to_parts<S: ::writeable::PartsWrite +
?Sized>(&self, sink: &mut S) -> core::fmt::Result {
(self.as_str()).write_to_parts(sink)
}
#[inline]
fn writeable_length_hint(&self) -> ::writeable::LengthHint {
(self.as_str()).writeable_length_hint()
}
#[inline]
fn writeable_borrow(&self) -> Option<&str> {
(self.as_str()).writeable_borrow()
}
}
impl core::fmt::Display for Key {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
::writeable::Writeable::write_to(&self, f)
}
}
#[doc =
"A macro allowing for compile-time construction of valid [`Key`] subtags."]
#[doc = " icu_locale_core::extensions::transform::key!(\"k0\"),"]
#[doc =
" \"k0\".parse::<icu_locale_core::extensions::transform::Key>().unwrap()"]
#[doc = "icu_locale_core::extensions::transform::key!(\"\");"]
#[doc = "[`Key`]: crate::extensions::transform::Key"]
#[macro_export]
#[doc(hidden)]
macro_rules! extensions_transform_key {
($string : literal) =>
{
const
{
use crate :: extensions :: transform :: Key; match Key ::
try_from_utf8($string.as_bytes())
{
Ok(r) => r, _ => panic!
(concat!
("Invalid ", stringify! (extensions), "::", stringify!
(transform), "::", stringify! (Key), ": ", $string)),
}
}
};
}
#[doc(inline)]
pub use extensions_transform_key as key;
unsafe impl zerovec::ule::ULE for Key {
fn validate_bytes(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> {
let it = bytes.chunks_exact(size_of::<Self>());
if !it.remainder().is_empty() {
return Err(zerovec::ule::UleError::length::<Self>(bytes.len()));
}
for v in it {
let mut a = [0; size_of::<Self>()];
a.copy_from_slice(v);
if Self::try_from_raw(a).is_err() {
return Err(zerovec::ule::UleError::parse::<Self>());
}
}
Ok(())
}
}
impl zerovec::ule::NicheBytes<2> for Key {
const NICHE_BIT_PATTERN: [u8; 2] =
<tinystr::TinyAsciiStr<2>>::NICHE_BIT_PATTERN;
}
impl zerovec::ule::AsULE for Key {
type ULE = Self;
fn to_unaligned(self) -> Self::ULE { self }
fn from_unaligned(unaligned: Self::ULE) -> Self { unaligned }
}impl_tinystr_subtag!(
6 Key,
21 extensions::transform,
22 key,
23 extensions_transform_key,
24 2..=2,
25 s,
26 s.all_bytes()[0].is_ascii_alphabetic() && s.all_bytes()[1].is_ascii_digit(),
27 s.to_ascii_lowercase(),
28 s.all_bytes()[0].is_ascii_lowercase() && s.all_bytes()[1].is_ascii_digit(),
29 InvalidExtension,
30 ["k0"],
31 ["", "k", "0k", "k12"],
32);