summaryrefslogtreecommitdiffstats
path: root/vendor/icu_locid/src/extensions/other/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/icu_locid/src/extensions/other/mod.rs')
-rw-r--r--vendor/icu_locid/src/extensions/other/mod.rs61
1 files changed, 42 insertions, 19 deletions
diff --git a/vendor/icu_locid/src/extensions/other/mod.rs b/vendor/icu_locid/src/extensions/other/mod.rs
index 36dbc49b6..44d5c9cf8 100644
--- a/vendor/icu_locid/src/extensions/other/mod.rs
+++ b/vendor/icu_locid/src/extensions/other/mod.rs
@@ -41,13 +41,16 @@ pub use subtag::Subtag;
/// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag.");
///
/// let other = Other::from_vec_unchecked(b'a', vec![subtag1, subtag2]);
-/// assert_eq!(&other.to_string(), "-a-foo-bar");
+/// assert_eq!(&other.to_string(), "a-foo-bar");
/// ```
///
/// [`Other Use Extensions`]: https://unicode.org/reports/tr35/#other_extensions
/// [`Unicode Locale Identifier`]: https://unicode.org/reports/tr35/#Unicode_locale_identifier
#[derive(Clone, PartialEq, Eq, Debug, Default, Hash, PartialOrd, Ord)]
-pub struct Other((u8, Vec<Subtag>));
+pub struct Other {
+ ext: u8,
+ keys: Vec<Subtag>,
+}
impl Other {
/// A constructor which takes a pre-sorted list of [`Subtag`].
@@ -65,11 +68,11 @@ impl Other {
/// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag.");
///
/// let other = Other::from_vec_unchecked(b'a', vec![subtag1, subtag2]);
- /// assert_eq!(&other.to_string(), "-a-foo-bar");
+ /// assert_eq!(&other.to_string(), "a-foo-bar");
/// ```
- pub fn from_vec_unchecked(ext: u8, input: Vec<Subtag>) -> Self {
+ pub fn from_vec_unchecked(ext: u8, keys: Vec<Subtag>) -> Self {
assert!(ext.is_ascii_alphabetic());
- Self((ext, input))
+ Self { ext, keys }
}
pub(crate) fn try_from_iter(ext: u8, iter: &mut SubtagIterator) -> Result<Self, ParserError> {
@@ -89,6 +92,22 @@ impl Other {
Ok(Self::from_vec_unchecked(ext, keys))
}
+ /// Gets the tag character for this extension as a &str.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use icu::locid::Locale;
+ ///
+ /// let loc: Locale = "und-a-hello-world".parse().unwrap();
+ /// let other_ext = &loc.extensions.other[0];
+ /// assert_eq!(other_ext.get_ext_str(), "a");
+ /// ```
+ pub fn get_ext_str(&self) -> &str {
+ debug_assert!(self.ext.is_ascii_alphabetic());
+ unsafe { core::str::from_utf8_unchecked(core::slice::from_ref(&self.ext)) }
+ }
+
/// Gets the tag character for this extension as a char.
///
/// # Examples
@@ -101,7 +120,7 @@ impl Other {
/// assert_eq!(other_ext.get_ext(), 'a');
/// ```
pub fn get_ext(&self) -> char {
- self.get_ext_byte() as char
+ self.ext as char
}
/// Gets the tag character for this extension as a byte.
@@ -116,19 +135,15 @@ impl Other {
/// assert_eq!(other_ext.get_ext_byte(), b'a');
/// ```
pub fn get_ext_byte(&self) -> u8 {
- self.0 .0
+ self.ext
}
pub(crate) fn for_each_subtag_str<E, F>(&self, f: &mut F) -> Result<(), E>
where
F: FnMut(&str) -> Result<(), E>,
{
- let (ext, keys) = &self.0;
- debug_assert!(ext.is_ascii_alphabetic());
- // Safety: ext is ascii_alphabetic, so it is valid UTF-8
- let ext_str = unsafe { core::str::from_utf8_unchecked(core::slice::from_ref(ext)) };
- f(ext_str)?;
- keys.iter().map(|t| t.as_str()).try_for_each(f)
+ f(self.get_ext_str())?;
+ self.keys.iter().map(|t| t.as_str()).try_for_each(f)
}
}
@@ -136,10 +151,8 @@ writeable::impl_display_with_writeable!(Other);
impl writeable::Writeable for Other {
fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
- let (ext, keys) = &self.0;
- sink.write_char('-')?;
- sink.write_char(*ext as char)?;
- for key in keys.iter() {
+ sink.write_str(self.get_ext_str())?;
+ for key in self.keys.iter() {
sink.write_char('-')?;
writeable::Writeable::write_to(key, sink)?;
}
@@ -148,10 +161,20 @@ impl writeable::Writeable for Other {
}
fn writeable_length_hint(&self) -> writeable::LengthHint {
- let mut result = writeable::LengthHint::exact(2);
- for key in self.0 .1.iter() {
+ let mut result = writeable::LengthHint::exact(1);
+ for key in self.keys.iter() {
result += writeable::Writeable::writeable_length_hint(key) + 1;
}
result
}
+
+ fn write_to_string(&self) -> alloc::borrow::Cow<str> {
+ if self.keys.is_empty() {
+ return alloc::borrow::Cow::Borrowed(self.get_ext_str());
+ }
+ let mut string =
+ alloc::string::String::with_capacity(self.writeable_length_hint().capacity());
+ let _ = self.write_to(&mut string);
+ alloc::borrow::Cow::Owned(string)
+ }
}