From 4f9fe856a25ab29345b90e7725509e9ee38a37be Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:41 +0200 Subject: Adding upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/icu_list/src/provider/mod.rs | 261 ++++++++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 vendor/icu_list/src/provider/mod.rs (limited to 'vendor/icu_list/src/provider/mod.rs') diff --git a/vendor/icu_list/src/provider/mod.rs b/vendor/icu_list/src/provider/mod.rs new file mode 100644 index 000000000..efab7c8bc --- /dev/null +++ b/vendor/icu_list/src/provider/mod.rs @@ -0,0 +1,261 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +// Provider structs must be stable +#![allow(clippy::exhaustive_structs, clippy::exhaustive_enums)] + +//! 🚧 \[Unstable\] Data provider struct definitions for this ICU4X component. +//! +//!
+//! 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways, +//! including in SemVer minor releases. While the serde representation of data structs is guaranteed +//! to be stable, their Rust representation might not be. Use with caution. +//!
+//! +//! Read more about data providers: [`icu_provider`] + +use crate::ListLength; +use alloc::borrow::Cow; +use icu_provider::DataMarker; +use icu_provider::{yoke, zerofrom}; + +mod serde_dfa; +pub use serde_dfa::SerdeDFA; + +/// Symbols and metadata required for [`ListFormatter`](crate::ListFormatter). +/// +///
+/// 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways, +/// including in SemVer minor releases. While the serde representation of data structs is guaranteed +/// to be stable, their Rust representation might not be. Use with caution. +///
+#[icu_provider::data_struct( + AndListV1Marker = "list/and@1", + OrListV1Marker = "list/or@1", + UnitListV1Marker = "list/unit@1" +)] +#[derive(Clone, Debug)] +#[cfg_attr( + feature = "datagen", + derive(serde::Serialize, databake::Bake), + databake(path = icu_list::provider), +)] +pub struct ListFormatterPatternsV1<'data>( + #[cfg_attr(feature = "datagen", serde(with = "deduplicating_array"))] + /// The patterns in the order start, middle, end, pair, short_start, short_middle, + /// short_end, short_pair, narrow_start, narrow_middle, narrow_end, narrow_pair, + pub [ConditionalListJoinerPattern<'data>; 12], +); + +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for ListFormatterPatternsV1<'de> { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + #[cfg(not(feature = "serde_human"))] + if deserializer.is_human_readable() { + use serde::de::Error; + return Err(D::Error::custom( + "Deserializing human-readable ListFormatter data requires the 'serde_human' feature", + )); + } + + Ok(ListFormatterPatternsV1(deduplicating_array::deserialize( + deserializer, + )?)) + } +} + +pub(crate) struct ErasedListV1Marker; + +impl DataMarker for ErasedListV1Marker { + type Yokeable = ListFormatterPatternsV1<'static>; +} + +impl<'data> ListFormatterPatternsV1<'data> { + pub(crate) fn start(&self, style: ListLength) -> &ConditionalListJoinerPattern<'data> { + #![allow(clippy::indexing_slicing)] // style as usize < 3 + &self.0[4 * (style as usize)] + } + + pub(crate) fn middle(&self, style: ListLength) -> &ConditionalListJoinerPattern<'data> { + #![allow(clippy::indexing_slicing)] // style as usize < 3 + &self.0[4 * (style as usize) + 1] + } + + pub(crate) fn end(&self, style: ListLength) -> &ConditionalListJoinerPattern<'data> { + #![allow(clippy::indexing_slicing)] // style as usize < 3 + &self.0[4 * (style as usize) + 2] + } + + pub(crate) fn pair(&self, style: ListLength) -> &ConditionalListJoinerPattern<'data> { + #![allow(clippy::indexing_slicing)] // style as usize < 3 + &self.0[4 * (style as usize) + 3] + } +} + +/// A pattern that can behave conditionally on the next element. +/// +///
+/// 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways, +/// including in SemVer minor releases. While the serde representation of data structs is guaranteed +/// to be stable, their Rust representation might not be. Use with caution. +///
+#[derive(Clone, Debug, yoke::Yokeable, zerofrom::ZeroFrom)] +#[cfg_attr( + feature = "datagen", + derive(PartialEq, serde::Serialize, databake::Bake), + databake(path = icu_list::provider), +)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +pub struct ConditionalListJoinerPattern<'data> { + /// The default pattern + #[cfg_attr(feature = "serde", serde(borrow))] + pub default: ListJoinerPattern<'data>, + /// And optional special case + #[cfg_attr( + feature = "serde", + serde(borrow, deserialize_with = "SpecialCasePattern::deserialize_option") + )] + pub special_case: Option>, +} + +/// The special case of a [`ConditionalListJoinerPattern`] +/// +///
+/// 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways, +/// including in SemVer minor releases. While the serde representation of data structs is guaranteed +/// to be stable, their Rust representation might not be. Use with caution. +///
+#[derive(Clone, Debug, yoke::Yokeable, zerofrom::ZeroFrom)] +#[cfg_attr( + feature = "datagen", + derive(PartialEq, serde::Serialize, databake::Bake), + databake(path = icu_list::provider), +)] +pub struct SpecialCasePattern<'data> { + /// The condition on the following element + pub condition: SerdeDFA<'data>, + /// The pattern if the condition matches + pub pattern: ListJoinerPattern<'data>, +} + +#[cfg(feature = "serde")] +impl<'data> SpecialCasePattern<'data> { + // If the condition doesn't deserialize, the whole special case becomes `None` + fn deserialize_option<'de: 'data, D>(deserializer: D) -> Result, D::Error> + where + D: serde::de::Deserializer<'de>, + { + use serde::Deserialize; + + #[derive(Deserialize)] + struct SpecialCasePatternOptionalDfa<'data> { + #[cfg_attr( + feature = "serde", + serde(borrow, deserialize_with = "SerdeDFA::maybe_deserialize") + )] + pub condition: Option>, + #[cfg_attr(feature = "serde", serde(borrow))] + pub pattern: ListJoinerPattern<'data>, + } + + Ok( + match Option::>::deserialize(deserializer)? { + Some(SpecialCasePatternOptionalDfa { + condition: Some(condition), + pattern, + }) => Some(SpecialCasePattern { condition, pattern }), + _ => None, + }, + ) + } +} + +/// A pattern containing two numeric placeholders ("{0}, and {1}.") +/// +///
+/// 🚧 This code is considered unstable; it may change at any time, in breaking or non-breaking ways, +/// including in SemVer minor releases. While the serde representation of data structs is guaranteed +/// to be stable, their Rust representation might not be. Use with caution. +///
+#[derive(Clone, Debug, PartialEq, yoke::Yokeable, zerofrom::ZeroFrom)] +#[cfg_attr(feature = "datagen", derive(serde::Serialize))] +pub struct ListJoinerPattern<'data> { + /// The pattern string without the placeholders + pub(crate) string: Cow<'data, str>, + /// The index of the first placeholder. Always <= index_1. + // Always 0 for CLDR data, so we don't need to serialize it. + // In-memory we have free space for it as index_1 doesn't + // fill a word. + #[cfg_attr(feature = "datagen", serde(skip))] + pub(crate) index_0: u8, + /// The index of the second placeholder. Always < string.len(). + pub(crate) index_1: u8, +} + +#[cfg(feature = "serde")] +impl<'de: 'data, 'data> serde::Deserialize<'de> for ListJoinerPattern<'data> { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(serde::Deserialize)] + struct Dummy<'data> { + #[cfg_attr(feature = "serde", serde(borrow))] + string: Cow<'data, str>, + index_1: u8, + } + let Dummy { string, index_1 } = Dummy::deserialize(deserializer)?; + + if index_1 as usize > string.len() { + use serde::de::Error; + Err(D::Error::custom("invalid index_1")) + } else { + Ok(ListJoinerPattern { + string, + index_0: 0, + index_1, + }) + } + } +} + +impl<'a> ListJoinerPattern<'a> { + /// Constructs a [`ListJoinerPattern`] from raw parts. Used by databake. + /// + /// # Safety + /// index_1 may be at most string.len() + pub const unsafe fn from_parts_unchecked(string: &'a str, index_1: u8) -> Self { + Self { + string: Cow::Borrowed(string), + index_0: 0, + index_1, + } + } +} + +#[cfg(feature = "datagen")] +impl databake::Bake for ListJoinerPattern<'_> { + fn bake(&self, env: &databake::CrateEnv) -> databake::TokenStream { + env.insert("icu_list"); + let string = (&*self.string).bake(env); + let index_1 = self.index_1.bake(env); + // Safe because our own data is safe + databake::quote! { unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(#string, #index_1) + }} + } +} + +#[cfg(all(test, feature = "datagen"))] +#[test] +fn databake() { + databake::test_bake!( + ListJoinerPattern, + const: unsafe { crate::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) }, + icu_list + ); +} -- cgit v1.2.3