diff options
Diffstat (limited to '')
-rw-r--r-- | vendor/icu_locid/src/extensions/mod.rs | 29 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/other/mod.rs | 61 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/other/subtag.rs | 6 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/private/mod.rs | 26 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/transform/fields.rs | 30 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/transform/mod.rs | 6 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/transform/value.rs | 35 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/unicode/attributes.rs | 15 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/unicode/keywords.rs | 65 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/unicode/mod.rs | 46 | ||||
-rw-r--r-- | vendor/icu_locid/src/extensions/unicode/value.rs | 33 |
11 files changed, 201 insertions, 151 deletions
diff --git a/vendor/icu_locid/src/extensions/mod.rs b/vendor/icu_locid/src/extensions/mod.rs index 42bfcd3c9..a6a189b11 100644 --- a/vendor/icu_locid/src/extensions/mod.rs +++ b/vendor/icu_locid/src/extensions/mod.rs @@ -102,11 +102,11 @@ impl ExtensionType { #[derive(Debug, Default, PartialEq, Eq, Clone, Hash)] #[non_exhaustive] pub struct Extensions { - /// A representation of the data for a Unicode extension, when present in the locale identifer. + /// A representation of the data for a Unicode extension, when present in the locale identifier. pub unicode: Unicode, - /// A representation of the data for a transform extension, when present in the locale identifer. + /// A representation of the data for a transform extension, when present in the locale identifier. pub transform: Transform, - /// A representation of the data for a private-use extension, when present in the locale identifer. + /// A representation of the data for a private-use extension, when present in the locale identifier. pub private: Private, /// A sequence of any other extensions that are present in the locale identifier but are not formally /// [defined](https://unicode.org/reports/tr35/) and represented explicitly as [`Unicode`], [`Transform`], @@ -210,19 +210,33 @@ impl Extensions { let mut private = None; let mut other = Vec::new(); - let mut st = iter.next(); - while let Some(subtag) = st { + while let Some(subtag) = iter.next() { + if subtag.is_empty() { + return Err(ParserError::InvalidExtension); + } match subtag.get(0).map(|b| ExtensionType::try_from_byte(*b)) { Some(Ok(ExtensionType::Unicode)) => { + if unicode.is_some() { + return Err(ParserError::DuplicatedExtension); + } unicode = Some(Unicode::try_from_iter(iter)?); } Some(Ok(ExtensionType::Transform)) => { + if transform.is_some() { + return Err(ParserError::DuplicatedExtension); + } transform = Some(Transform::try_from_iter(iter)?); } Some(Ok(ExtensionType::Private)) => { + if private.is_some() { + return Err(ParserError::DuplicatedExtension); + } private = Some(Private::try_from_iter(iter)?); } Some(Ok(ExtensionType::Other(ext))) => { + if other.iter().any(|o: &Other| o.get_ext_byte() == ext) { + return Err(ParserError::DuplicatedExtension); + } let parsed = Other::try_from_iter(ext, iter)?; if let Err(idx) = other.binary_search(&parsed) { other.insert(idx, parsed); @@ -230,11 +244,8 @@ impl Extensions { return Err(ParserError::InvalidExtension); } } - None => {} _ => return Err(ParserError::InvalidExtension), } - - st = iter.next(); } Ok(Self { @@ -283,7 +294,7 @@ impl_writeable_for_each_subtag_str_no_test!(Extensions); fn test_writeable() { use crate::Locale; use writeable::assert_writeable_eq; - assert_writeable_eq!(Extensions::new(), "",); + assert_writeable_eq!(Extensions::new(), ""); assert_writeable_eq!( "my-t-my-d0-zawgyi".parse::<Locale>().unwrap().extensions, "t-my-d0-zawgyi", 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) + } } diff --git a/vendor/icu_locid/src/extensions/other/subtag.rs b/vendor/icu_locid/src/extensions/other/subtag.rs index 60995c395..ad4d6a0f2 100644 --- a/vendor/icu_locid/src/extensions/other/subtag.rs +++ b/vendor/icu_locid/src/extensions/other/subtag.rs @@ -11,11 +11,9 @@ impl_tinystr_subtag!( /// # Examples /// /// ``` - /// use icu::locid::extensions::other::Subtag; + /// use icu::locid::extensions_other_subtag as subtag; /// - /// let subtag: Subtag = "Foo".parse().expect("Failed to parse a Subtag."); - /// - /// assert_eq!(subtag.as_str(), "foo"); + /// assert_eq!(subtag!("Foo").as_str(), "foo"); /// ``` Subtag, extensions::other::Subtag, diff --git a/vendor/icu_locid/src/extensions/private/mod.rs b/vendor/icu_locid/src/extensions/private/mod.rs index 13090c94a..8382d166f 100644 --- a/vendor/icu_locid/src/extensions/private/mod.rs +++ b/vendor/icu_locid/src/extensions/private/mod.rs @@ -13,16 +13,18 @@ //! # Examples //! //! ``` -//! use icu::locid::extensions::private::{Private, Subtag}; -//! use icu::locid::Locale; +//! use icu::locid::extensions_private_subtag as subtag; +//! use icu::locid::{locale, Locale}; //! //! let mut loc: Locale = "en-US-x-foo-faa".parse().expect("Parsing failed."); //! -//! let subtag: Subtag = "foo".parse().expect("Parsing subtag failed."); -//! assert!(loc.extensions.private.contains(&subtag)); -//! assert_eq!(loc.extensions.private.iter().next(), Some(&subtag)); +//! assert!(loc.extensions.private.contains(&subtag!("foo"))); +//! assert_eq!(loc.extensions.private.iter().next(), Some(&subtag!("foo"))); +//! //! loc.extensions.private.clear(); -//! assert_eq!(loc.to_string(), "en-US"); +//! +//! assert!(loc.extensions.private.is_empty()); +//! assert_eq!(loc, locale!("en-US")); //! ``` mod other; @@ -50,7 +52,7 @@ use crate::parser::SubtagIterator; /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// /// let private = Private::from_vec_unchecked(vec![subtag1, subtag2]); -/// assert_eq!(&private.to_string(), "-x-foo-bar"); +/// assert_eq!(&private.to_string(), "x-foo-bar"); /// ``` /// /// [`Private Use Extensions`]: https://unicode.org/reports/tr35/#pu_extensions @@ -84,7 +86,7 @@ impl Private { /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// /// let private = Private::from_vec_unchecked(vec![subtag1, subtag2]); - /// assert_eq!(&private.to_string(), "-x-foo-bar"); + /// assert_eq!(&private.to_string(), "x-foo-bar"); /// ``` pub fn from_vec_unchecked(input: Vec<Subtag>) -> Self { Self(input) @@ -101,11 +103,11 @@ impl Private { /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// let mut private = Private::from_vec_unchecked(vec![subtag1, subtag2]); /// - /// assert_eq!(&private.to_string(), "-x-foo-bar"); + /// assert_eq!(&private.to_string(), "x-foo-bar"); /// /// private.clear(); /// - /// assert_eq!(&private.to_string(), ""); + /// assert_eq!(private, Private::new()); /// ``` pub fn clear(&mut self) { self.0.clear(); @@ -138,7 +140,7 @@ impl writeable::Writeable for Private { if self.is_empty() { return Ok(()); } - sink.write_str("-x")?; + sink.write_str("x")?; for key in self.iter() { sink.write_char('-')?; writeable::Writeable::write_to(key, sink)?; @@ -150,7 +152,7 @@ impl writeable::Writeable for Private { if self.is_empty() { return writeable::LengthHint::exact(0); } - let mut result = writeable::LengthHint::exact(2); + let mut result = writeable::LengthHint::exact(1); for key in self.iter() { result += writeable::Writeable::writeable_length_hint(key) + 1; } diff --git a/vendor/icu_locid/src/extensions/transform/fields.rs b/vendor/icu_locid/src/extensions/transform/fields.rs index ca10000a7..f08581a87 100644 --- a/vendor/icu_locid/src/extensions/transform/fields.rs +++ b/vendor/icu_locid/src/extensions/transform/fields.rs @@ -25,10 +25,10 @@ use super::Value; /// /// ``` /// use icu::locid::extensions::transform::{Fields, Key, Value}; +/// use icu::locid::extensions_transform_key as key; /// -/// let key: Key = "h0".parse().expect("Failed to parse a Key."); -/// let value: Value = "hybrid".parse().expect("Failed to parse a Value."); -/// let fields: Fields = vec![(key, value)].into_iter().collect(); +/// let value = "hybrid".parse::<Value>().expect("Failed to parse a Value."); +/// let fields = vec![(key!("h0"), value)].into_iter().collect::<Fields>(); /// /// assert_eq!(&fields.to_string(), "h0-hybrid"); /// ``` @@ -76,17 +76,17 @@ impl Fields { /// # Examples /// /// ``` - /// use icu::locid::extensions::transform::{Fields, Key, Value}; + /// use icu::locid::extensions::transform::{Fields, Value}; + /// use icu::locid::extensions_transform_key as key; /// - /// let key: Key = "h0".parse().expect("Failed to parse a Key."); - /// let value: Value = "hybrid".parse().expect("Failed to parse a Value."); - /// let mut fields: Fields = vec![(key, value)].into_iter().collect(); + /// let value = "hybrid".parse::<Value>().expect("Failed to parse a Value."); + /// let mut fields = vec![(key!("h0"), value)].into_iter().collect::<Fields>(); /// /// assert_eq!(&fields.to_string(), "h0-hybrid"); /// /// fields.clear(); /// - /// assert_eq!(&fields.to_string(), ""); + /// assert_eq!(fields, Fields::new()); /// ``` pub fn clear(&mut self) -> Self { core::mem::take(self) @@ -122,16 +122,14 @@ impl Fields { /// /// ``` /// use icu::locid::extensions::transform::{Fields, Key, Value}; + /// use icu::locid::extensions_transform_key as key; /// - /// let key: Key = "h0".parse().expect("Failed to parse a Key."); - /// let value: Value = "hybrid".parse().expect("Failed to parse a Value."); - /// let mut fields: Fields = vec![(key, value)].into_iter().collect(); + /// let value = "hybrid".parse::<Value>().unwrap(); + /// let fields = vec![(key!("h0"), value.clone())] + /// .into_iter() + /// .collect::<Fields>(); /// - /// let key: Key = "h0".parse().expect("Failed to parse a Key."); - /// assert_eq!( - /// fields.get(&key).map(|v| v.to_string()), - /// Some("hybrid".to_string()) - /// ); + /// assert_eq!(fields.get(&key!("h0")), Some(&value)); /// ``` pub fn get<Q>(&self, key: &Q) -> Option<&Value> where diff --git a/vendor/icu_locid/src/extensions/transform/mod.rs b/vendor/icu_locid/src/extensions/transform/mod.rs index a8c605146..7b97d87f6 100644 --- a/vendor/icu_locid/src/extensions/transform/mod.rs +++ b/vendor/icu_locid/src/extensions/transform/mod.rs @@ -28,7 +28,7 @@ //! assert!(loc.extensions.transform.fields.contains_key(&key)); //! assert_eq!(loc.extensions.transform.fields.get(&key), Some(&value)); //! -//! assert_eq!(&loc.extensions.transform.to_string(), "-t-es-AR-h0-hybrid"); +//! assert_eq!(&loc.extensions.transform.to_string(), "t-es-AR-h0-hybrid"); //! ``` mod fields; mod key; @@ -208,7 +208,7 @@ impl writeable::Writeable for Transform { if self.is_empty() { return Ok(()); } - sink.write_str("-t")?; + sink.write_str("t")?; if let Some(lang) = &self.lang { sink.write_char('-')?; writeable::Writeable::write_to(lang, sink)?; @@ -224,7 +224,7 @@ impl writeable::Writeable for Transform { if self.is_empty() { return writeable::LengthHint::exact(0); } - let mut result = writeable::LengthHint::exact(2); + let mut result = writeable::LengthHint::exact(1); if let Some(lang) = &self.lang { result += writeable::Writeable::writeable_length_hint(lang) + 1; } diff --git a/vendor/icu_locid/src/extensions/transform/value.rs b/vendor/icu_locid/src/extensions/transform/value.rs index 84468361a..f908b0208 100644 --- a/vendor/icu_locid/src/extensions/transform/value.rs +++ b/vendor/icu_locid/src/extensions/transform/value.rs @@ -2,7 +2,7 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use crate::parser::{get_subtag_iterator, ParserError}; +use crate::parser::{ParserError, SubtagIterator}; use alloc::vec; use alloc::vec::Vec; use core::ops::RangeInclusive; @@ -16,20 +16,18 @@ use tinystr::TinyAsciiStr; /// Each part of the sequence has to be no shorter than three characters and no /// longer than 8. /// -/// /// # Examples /// /// ``` /// use icu::locid::extensions::transform::Value; /// -/// let value1: Value = "hybrid".parse().expect("Failed to parse a Value."); -/// let value2: Value = -/// "hybrid-foobar".parse().expect("Failed to parse a Value."); +/// "hybrid".parse::<Value>().expect("Valid Value."); +/// +/// "hybrid-foobar".parse::<Value>().expect("Valid Value."); /// -/// assert_eq!(&value1.to_string(), "hybrid"); -/// assert_eq!(&value2.to_string(), "hybrid-foobar"); +/// "no".parse::<Value>().expect_err("Invalid Value."); /// ``` -#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Default)] pub struct Value(Vec<TinyAsciiStr<{ *TYPE_LENGTH.end() }>>); const TYPE_LENGTH: RangeInclusive<usize> = 3..=8; @@ -45,14 +43,12 @@ impl Value { /// use icu::locid::extensions::transform::Value; /// /// let value = Value::try_from_bytes(b"hybrid").expect("Parsing failed."); - /// - /// assert_eq!(&value.to_string(), "hybrid"); /// ``` pub fn try_from_bytes(input: &[u8]) -> Result<Self, ParserError> { let mut v = vec![]; let mut has_value = false; - for subtag in get_subtag_iterator(input) { + for subtag in SubtagIterator::new(input) { if !Self::is_type_subtag(subtag) { return Err(ParserError::InvalidExtension); } @@ -116,4 +112,19 @@ impl FromStr for Value { } } -impl_writeable_for_tinystr_list!(Value, "true", "hybrid", "foobar"); +impl_writeable_for_each_subtag_str_no_test!(Value, selff, selff.0.is_empty() => alloc::borrow::Cow::Borrowed("true")); + +#[test] +fn test_writeable() { + use writeable::assert_writeable_eq; + + let hybrid = "hybrid".parse().unwrap(); + let foobar = "foobar".parse().unwrap(); + + assert_writeable_eq!(Value::default(), "true"); + assert_writeable_eq!(Value::from_vec_unchecked(vec![hybrid]), "hybrid"); + assert_writeable_eq!( + Value::from_vec_unchecked(vec![hybrid, foobar]), + "hybrid-foobar" + ); +} diff --git a/vendor/icu_locid/src/extensions/unicode/attributes.rs b/vendor/icu_locid/src/extensions/unicode/attributes.rs index 1f9536bfa..e58fb04da 100644 --- a/vendor/icu_locid/src/extensions/unicode/attributes.rs +++ b/vendor/icu_locid/src/extensions/unicode/attributes.rs @@ -79,18 +79,19 @@ impl Attributes { /// /// ``` /// use icu::locid::extensions::unicode::{Attribute, Attributes}; + /// use icu::locid::extensions_unicode_attribute as attribute; + /// use writeable::assert_writeable_eq; /// - /// let attribute1: Attribute = "foobar".parse().expect("Parsing failed."); - /// let attribute2: Attribute = "testing".parse().expect("Parsing failed."); - /// let mut v = vec![attribute1, attribute2]; - /// - /// let mut attributes: Attributes = Attributes::from_vec_unchecked(v); + /// let mut attributes = Attributes::from_vec_unchecked(vec![ + /// attribute!("foobar"), + /// attribute!("testing"), + /// ]); /// - /// assert_eq!(attributes.to_string(), "foobar-testing"); + /// assert_writeable_eq!(attributes, "foobar-testing"); /// /// attributes.clear(); /// - /// assert_eq!(attributes.to_string(), ""); + /// assert_writeable_eq!(attributes, ""); /// ``` pub fn clear(&mut self) -> Self { core::mem::take(self) diff --git a/vendor/icu_locid/src/extensions/unicode/keywords.rs b/vendor/icu_locid/src/extensions/unicode/keywords.rs index dc9a15921..580cacaf1 100644 --- a/vendor/icu_locid/src/extensions/unicode/keywords.rs +++ b/vendor/icu_locid/src/extensions/unicode/keywords.rs @@ -29,11 +29,14 @@ use crate::ordering::SubtagOrderingResult; /// Manually build up a [`Keywords`] object: /// /// ``` -/// use icu::locid::extensions::unicode::{Key, Keywords, Value}; +/// use icu::locid::{ +/// extensions::unicode::Keywords, extensions_unicode_key as key, +/// extensions_unicode_value as value, locale, +/// }; /// -/// let key: Key = "hc".parse().expect("Failed to parse a Key."); -/// let value: Value = "h23".parse().expect("Failed to parse a Value."); -/// let keywords: Keywords = vec![(key, value)].into_iter().collect(); +/// let keywords = vec![(key!("hc"), value!("h23"))] +/// .into_iter() +/// .collect::<Keywords>(); /// /// assert_eq!(&keywords.to_string(), "hc-h23"); /// ``` @@ -113,15 +116,16 @@ impl Keywords { /// # Examples /// /// ``` - /// use icu::locid::extensions::unicode::{Key, Keywords, Value}; - /// use litemap::LiteMap; + /// use icu::locid::{ + /// extensions::unicode::Keywords, extensions_unicode_key as key, + /// extensions_unicode_value as value, + /// }; /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// let value: Value = "gregory".parse().expect("Failed to parse a Value."); - /// let keywords: Keywords = vec![(key, value)].into_iter().collect(); + /// let keywords = vec![(key!("ca"), value!("gregory"))] + /// .into_iter() + /// .collect::<Keywords>(); /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// assert!(&keywords.contains_key(&key)); + /// assert!(&keywords.contains_key(&key!("ca"))); /// ``` pub fn contains_key<Q>(&self, key: &Q) -> bool where @@ -137,17 +141,16 @@ impl Keywords { /// # Examples /// /// ``` - /// use icu::locid::extensions::unicode::{Key, Keywords, Value}; + /// use icu::locid::{ + /// extensions::unicode::Keywords, extensions_unicode_key as key, + /// extensions_unicode_value as value, + /// }; /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// let value: Value = "buddhist".parse().expect("Failed to parse a Value."); - /// let keywords: Keywords = vec![(key, value)].into_iter().collect(); + /// let keywords = vec![(key!("ca"), value!("buddhist"))] + /// .into_iter() + /// .collect::<Keywords>(); /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// assert_eq!( - /// keywords.get(&key).map(|v| v.to_string()), - /// Some("buddhist".to_string()) - /// ); + /// assert_eq!(keywords.get(&key!("ca")), Some(&value!("buddhist"))); /// ``` pub fn get<Q>(&self, key: &Q) -> Option<&Value> where @@ -164,20 +167,19 @@ impl Keywords { /// # Examples /// /// ``` - /// use icu::locid::extensions::unicode::{Key, Keywords, Value}; + /// use icu::locid::{ + /// extensions::unicode::Keywords, extensions_unicode_key as key, + /// extensions_unicode_value as value, + /// }; /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// let value: Value = "buddhist".parse().expect("Failed to parse a Value."); - /// let mut keywords: Keywords = vec![(key, value)].into_iter().collect(); + /// let mut keywords = vec![(key!("ca"), value!("buddhist"))] + /// .into_iter() + /// .collect::<Keywords>(); /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// if let Some(value) = keywords.get_mut(&key) { - /// *value = "gregory".parse().expect("Failed to parse a Value."); + /// if let Some(value) = keywords.get_mut(&key!("ca")) { + /// *value = value!("gregory"); /// } - /// assert_eq!( - /// keywords.get(&key).map(|v| v.to_string()), - /// Some("gregory".to_string()) - /// ); + /// assert_eq!(keywords.get(&key!("ca")), Some(&value!("gregory"))); /// ``` pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut Value> where @@ -308,7 +310,6 @@ impl Keywords { /// .extensions /// .unicode /// .keywords; - /// assert_eq!(a, a_kwds.to_string()); /// assert!(a_kwds.strict_cmp(a.as_bytes()) == Ordering::Equal); /// assert!(a_kwds.strict_cmp(b.as_bytes()) == Ordering::Less); /// } diff --git a/vendor/icu_locid/src/extensions/unicode/mod.rs b/vendor/icu_locid/src/extensions/unicode/mod.rs index fabf1036c..687a8c383 100644 --- a/vendor/icu_locid/src/extensions/unicode/mod.rs +++ b/vendor/icu_locid/src/extensions/unicode/mod.rs @@ -11,21 +11,24 @@ //! # Examples //! //! ``` -//! use icu::locid::extensions::unicode::{Attribute, Key, Unicode, Value}; -//! use icu::locid::{LanguageIdentifier, Locale}; +//! use icu::locid::Locale; +//! use icu::locid::{ +//! extensions::unicode::Unicode, +//! extensions_unicode_attribute as attribute, +//! extensions_unicode_key as key, extensions_unicode_value as value, +//! }; //! -//! let mut loc: Locale = -//! "en-US-u-foobar-hc-h12".parse().expect("Parsing failed."); +//! let loc: Locale = "en-US-u-foobar-hc-h12".parse().expect("Parsing failed."); //! -//! let key: Key = "hc".parse().expect("Parsing key failed."); -//! let value: Value = "h12".parse().expect("Parsing value failed."); -//! let attribute: Attribute = -//! "foobar".parse().expect("Parsing attribute failed."); -//! -//! assert_eq!(loc.extensions.unicode.keywords.get(&key), Some(&value)); -//! assert!(loc.extensions.unicode.attributes.contains(&attribute)); -//! -//! assert_eq!(&loc.extensions.unicode.to_string(), "-u-foobar-hc-h12"); +//! assert_eq!( +//! loc.extensions.unicode.keywords.get(&key!("hc")), +//! Some(&value!("h12")) +//! ); +//! assert!(loc +//! .extensions +//! .unicode +//! .attributes +//! .contains(&attribute!("foobar"))); //! ``` mod attribute; mod attributes; @@ -60,15 +63,18 @@ use litemap::LiteMap; /// # Examples /// /// ``` -/// use icu::locid::extensions::unicode::{Key, Value}; /// use icu::locid::Locale; +/// use icu::locid::{ +/// extensions_unicode_key as key, extensions_unicode_value as value, +/// }; /// -/// let mut loc: Locale = +/// let loc: Locale = /// "de-u-hc-h12-ca-buddhist".parse().expect("Parsing failed."); /// -/// let key: Key = "ca".parse().expect("Parsing key failed."); -/// let value: Value = "buddhist".parse().expect("Parsing value failed."); -/// assert_eq!(loc.extensions.unicode.keywords.get(&key), Some(&value)); +/// assert_eq!( +/// loc.extensions.unicode.keywords.get(&key!("ca")), +/// Some(&value!("buddhist")) +/// ); /// ``` #[derive(Clone, PartialEq, Eq, Debug, Default, Hash, PartialOrd, Ord)] #[allow(clippy::exhaustive_structs)] // spec-backed stable datastructure @@ -205,7 +211,7 @@ impl writeable::Writeable for Unicode { if self.is_empty() { return Ok(()); } - sink.write_str("-u")?; + sink.write_str("u")?; if !self.attributes.is_empty() { sink.write_char('-')?; writeable::Writeable::write_to(&self.attributes, sink)?; @@ -221,7 +227,7 @@ impl writeable::Writeable for Unicode { if self.is_empty() { return writeable::LengthHint::exact(0); } - let mut result = writeable::LengthHint::exact(2); + let mut result = writeable::LengthHint::exact(1); if !self.attributes.is_empty() { result += writeable::Writeable::writeable_length_hint(&self.attributes) + 1; } diff --git a/vendor/icu_locid/src/extensions/unicode/value.rs b/vendor/icu_locid/src/extensions/unicode/value.rs index ce9982a4c..e6374372c 100644 --- a/vendor/icu_locid/src/extensions/unicode/value.rs +++ b/vendor/icu_locid/src/extensions/unicode/value.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::helpers::ShortVec; -use crate::parser::{get_subtag_iterator, ParserError}; +use crate::parser::{ParserError, SubtagIterator}; use alloc::vec::Vec; use core::ops::RangeInclusive; use core::str::FromStr; @@ -20,20 +20,21 @@ use tinystr::TinyAsciiStr; /// # Examples /// /// ``` -/// use icu::locid::extensions::unicode::Value; -/// -/// let value1: Value = "gregory".parse().expect("Failed to parse a Value."); -/// let value2: Value = -/// "islamic-civil".parse().expect("Failed to parse a Value."); -/// let value3: Value = "true".parse().expect("Failed to parse a Value."); +/// use icu::locid::{ +/// extensions::unicode::Value, extensions_unicode_value as value, +/// }; +/// use writeable::assert_writeable_eq; /// -/// assert_eq!(&value1.to_string(), "gregory"); -/// assert_eq!(&value2.to_string(), "islamic-civil"); +/// assert_writeable_eq!(value!("gregory"), "gregory"); +/// assert_writeable_eq!( +/// "islamic-civil".parse::<Value>().unwrap(), +/// "islamic-civil" +/// ); /// -/// // The value "true" is special-cased to an empty value -/// assert_eq!(&value3.to_string(), ""); +/// // The value "true" has the special, empty string representation +/// assert_eq!(value!("true").to_string(), ""); /// ``` -#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Default)] pub struct Value(ShortVec<TinyAsciiStr<{ *VALUE_LENGTH.end() }>>); const VALUE_LENGTH: RangeInclusive<usize> = 3..=8; @@ -48,15 +49,13 @@ impl Value { /// ``` /// use icu::locid::extensions::unicode::Value; /// - /// let value = Value::try_from_bytes(b"buddhist").expect("Parsing failed."); - /// - /// assert_eq!(&value.to_string(), "buddhist"); + /// Value::try_from_bytes(b"buddhist").expect("Parsing failed."); /// ``` pub fn try_from_bytes(input: &[u8]) -> Result<Self, ParserError> { let mut v = ShortVec::new(); if !input.is_empty() { - for subtag in get_subtag_iterator(input) { + for subtag in SubtagIterator::new(input) { let val = Self::subtag_from_bytes(subtag)?; if let Some(val) = val { v.push(val); @@ -153,7 +152,7 @@ impl FromStr for Value { } } -impl_writeable_for_tinystr_list!(Value, "", "islamic", "civil"); +impl_writeable_for_subtag_list!(Value, "islamic", "civil"); /// A macro allowing for compile-time construction of valid Unicode [`Value`] subtag. /// |