Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Pattern more directly #5531

Merged
merged 15 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion components/experimental/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ icu_properties = { workspace = true }
databake = { workspace = true, optional = true, features = ["derive"] }
either = { workspace = true }
fixed_decimal = { workspace = true }
icu_pattern = { workspace = true , features = ["alloc", "yoke", "zerofrom"]}
icu_pattern = { workspace = true , features = ["alloc", "yoke", "zerovec"]}
litemap = { workspace = true }
tinystr = { workspace = true, features = ["alloc", "zerovec"] }
potential_utf = { workspace = true, features = ["zerovec"] }
Expand Down
4 changes: 2 additions & 2 deletions components/experimental/src/dimension/provider/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ pub struct CurrencyEssentialsV1<'data> {
/// NOTE: place holder 0 is the place of the currency value.
/// place holder 1 is the place of the currency sign `¤`.
#[cfg_attr(feature = "serde", serde(borrow))]
pub standard_pattern: Option<DoublePlaceholderPattern<Cow<'data, str>>>,
pub standard_pattern: Option<Cow<'data, DoublePlaceholderPattern>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thought: I think we should do as you suggested in the other issue. We can export a ZeroCow type from zerovec that has the correct Serde impls and reduces one layer of struct construction in the Bake impl. (Not in this PR)


// TODO(#4677): Implement the pattern to accept the signed negative and signed positive patterns.
/// Represents the standard alpha_next_to_number pattern.
/// NOTE: place holder 0 is the place of the currency value.
/// place holder 1 is the place of the currency sign `¤`.
#[cfg_attr(feature = "serde", serde(borrow))]
pub standard_alpha_next_to_number_pattern: Option<DoublePlaceholderPattern<Cow<'data, str>>>,
pub standard_alpha_next_to_number_pattern: Option<Cow<'data, DoublePlaceholderPattern>>,

/// Contains all the place holders.
#[cfg_attr(feature = "serde", serde(borrow))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
//!
//! Read more about data providers: [`icu_provider`]

use crate::relativetime::provider::PluralPatterns;
use icu_pattern::DoublePlaceholder;
use icu_pattern::DoublePlaceholderPattern;
use icu_plurals::provider::PluralElementsPackedCow;
use icu_provider::prelude::*;

/// Currency Extended V1 data struct.
Expand All @@ -23,5 +23,5 @@ use icu_provider::prelude::*;
pub struct CurrencyPatternsDataV1<'data> {
/// Contains the unit patterns for a currency based on plural rules.
#[cfg_attr(feature = "serde", serde(borrow))]
pub patterns: PluralPatterns<'data, DoublePlaceholder>,
pub patterns: PluralElementsPackedCow<'data, DoublePlaceholderPattern>,
}
4 changes: 2 additions & 2 deletions components/experimental/src/dimension/provider/percent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ pub struct PercentEssentialsV1<'data> {
/// Represents the standard pattern for signed percents.
/// NOTE: place holder 0 is the place of the percent value.
/// place holder 1 is the place of the plus, minus, or approximate signs.
pub signed_pattern: DoublePlaceholderPattern<Cow<'data, str>>,
pub signed_pattern: Cow<'data, DoublePlaceholderPattern>,

#[cfg_attr(feature = "serde", serde(borrow))]
/// Represents the standard pattern for unsigned percents.
pub unsigned_pattern: SinglePlaceholderPattern<Cow<'data, str>>,
pub unsigned_pattern: Cow<'data, SinglePlaceholderPattern>,

#[cfg_attr(feature = "serde", serde(borrow))]
/// The localize approximate sign.
Expand Down
25 changes: 11 additions & 14 deletions components/experimental/src/dimension/provider/units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
//!
//! Read more about data providers: [`icu_provider`]

use crate::relativetime::provider::PluralPatterns;
use icu_pattern::SinglePlaceholder;
use icu_pattern::SinglePlaceholderPattern;
use icu_plurals::provider::PluralElementsPackedCow;
use icu_provider::prelude::*;

#[icu_provider::data_struct(marker(
Expand All @@ -26,7 +26,7 @@ pub struct UnitsDisplayNameV1<'data> {
// TODO: use `MeasureUnit` for the units key instead of strings.
/// Contains the long width patterns for the units.
#[cfg_attr(feature = "serde", serde(borrow))]
pub patterns: PluralPatterns<'data, SinglePlaceholder>,
pub patterns: PluralElementsPackedCow<'data, SinglePlaceholderPattern>,
}

impl<'data> UnitsDisplayNameV1<'data> {
Expand All @@ -37,17 +37,14 @@ impl<'data> UnitsDisplayNameV1<'data> {
/// The bytes must represent a valid [`icu_plurals::provider::PluralElementsPackedULE`]
pub const unsafe fn from_byte_slice_unchecked(bytes: &'data [u8]) -> Self {
Self {
patterns: PluralPatterns {
strings: icu_plurals::provider::PluralElementsPackedCow {
elements: alloc::borrow::Cow::Borrowed(
// Safety: this function's safety invariant guarantees that the bytes
// represent a valid `PluralElementsPackedULE`
icu_plurals::provider::PluralElementsPackedULE::from_byte_slice_unchecked(
bytes,
),
patterns: icu_plurals::provider::PluralElementsPackedCow {
elements: alloc::borrow::Cow::Borrowed(
// Safety: this function's safety invariant guarantees that the bytes
// represent a valid `PluralElementsPackedULE`
icu_plurals::provider::PluralElementsPackedULE::from_byte_slice_unchecked(
bytes,
),
},
_phantom: core::marker::PhantomData,
),
},
}
}
Expand All @@ -58,7 +55,7 @@ impl databake::Bake for UnitsDisplayNameV1<'_> {
fn bake(&self, ctx: &databake::CrateEnv) -> databake::TokenStream {
use zerovec::ule::VarULE;
ctx.insert("icu_experimental::dimension::provider::units");
let bytes = self.patterns.strings.elements.as_byte_slice().bake(ctx);
let bytes = self.patterns.elements.as_byte_slice().bake(ctx);
// Safety: The bytes are returned by `PluralElementsPackedULE::as_byte_slice`.
databake::quote! { unsafe {
icu_experimental::dimension::provider::units::UnitsDisplayNameV1::from_byte_slice_unchecked(#bytes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ pub fn derive_missing_initials(
initial_pattern_str: &str,
initial_sequence_pattern_str: &str,
) -> String {
let initial_pattern: SinglePlaceholderPattern<_> = initial_pattern_str.parse().unwrap();
let initial_sequence_pattern: DoublePlaceholderPattern<_> =
initial_sequence_pattern_str.parse().unwrap();
let initial_pattern =
SinglePlaceholderPattern::try_from_str(initial_pattern_str, Default::default()).unwrap();
let initial_sequence_pattern =
DoublePlaceholderPattern::try_from_str(initial_sequence_pattern_str, Default::default())
.unwrap();

if person_name.has_name_field(requested_field) {
return String::from(person_name.get(requested_field));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl FromStr for NameField {
pub fn to_person_name_pattern(value: &str) -> Result<PersonNamePattern, PersonNamesFormatterError> {
let mut name_fields_map: Vec<(NameField, Cow<str>)> = Vec::new();

let parsed_pattern = MultiNamedPlaceholderPattern::from_str(value)?;
let parsed_pattern = MultiNamedPlaceholderPattern::try_from_str(value, Default::default())?;

let mut current_name_field = None;
let mut current_literal = None;
Expand Down
131 changes: 5 additions & 126 deletions components/experimental/src/relativetime/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@
//!
//! Read more about data providers: [`icu_provider`]

use alloc::borrow::Cow;
use core::marker::PhantomData;
#[cfg(feature = "datagen")]
use core::{fmt::Debug, str::FromStr};
use icu_pattern::{Pattern, PatternBackend, SinglePlaceholder};
#[cfg(feature = "datagen")]
use icu_plurals::PluralElements;
use icu_plurals::{PluralCategory, PluralOperands, PluralRules};
use core::fmt::Debug;
use icu_pattern::SinglePlaceholderPattern;
use icu_plurals::provider::PluralElementsPackedCow;
use icu_provider::prelude::*;
use zerovec::ZeroMap;

Expand Down Expand Up @@ -71,127 +67,10 @@ pub struct RelativeTimePatternDataV1<'data> {
pub relatives: ZeroMap<'data, i8, str>,
/// How to display times in the past.
#[cfg_attr(feature = "serde", serde(borrow))]
pub past: PluralPatterns<'data, SinglePlaceholder>,
pub past: PluralElementsPackedCow<'data, SinglePlaceholderPattern>,
/// How to display times in the future.
#[cfg_attr(feature = "serde", serde(borrow))]
pub future: PluralPatterns<'data, SinglePlaceholder>,
}

#[derive(Debug)]
#[zerovec::make_varule(PluralCategoryStrULE)]
#[zerovec::skip_derive(Ord)]
#[zerovec::derive(Debug)]
#[cfg_attr(
feature = "serde",
derive(serde::Deserialize),
zerovec::derive(Deserialize)
)]
#[cfg_attr(
feature = "datagen",
derive(serde::Serialize),
zerovec::derive(Serialize)
)]
/// A tuple of [`PluralCategory`] and [`str`].
pub struct PluralCategoryStr<'data>(pub PluralCategory, pub Cow<'data, str>);

/// Display specification for relative times, split over potential plural patterns.
#[derive(Debug, PartialEq, yoke::Yokeable, zerofrom::ZeroFrom)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "datagen", derive(serde::Serialize, databake::Bake))]
#[cfg_attr(feature = "datagen", databake(path = icu_experimental::relativetime::provider))]
#[yoke(prove_covariance_manually)]
pub struct PluralPatterns<'data, B> {
#[cfg_attr(feature = "serde", serde(borrow))]
#[doc(hidden)] // databake only
pub strings: icu_plurals::provider::PluralElementsPackedCow<'data, str>,
#[cfg_attr(feature = "serde", serde(skip))]
#[doc(hidden)] // databake only
pub _phantom: PhantomData<B>,
}

impl<'data, B> Clone for PluralPatterns<'data, B> {
fn clone(&self) -> Self {
Self {
strings: self.strings.clone(),
_phantom: PhantomData,
}
}
}

impl<'data, B: PatternBackend<Store = str>> PluralPatterns<'data, B> {
/// Returns the pattern for the given [`PluralCategory`].
pub fn get(&'data self, op: PluralOperands, rules: &PluralRules) -> &'data Pattern<B, str> {
Pattern::from_ref_store_unchecked(self.strings.get(op, rules))
}
}

#[cfg(feature = "datagen")]
impl<'data, B: PatternBackend<Store = str>> TryFrom<PluralElements<&'data str>>
for PluralPatterns<'static, B>
where
B::PlaceholderKeyCow<'data>: FromStr,
<B::PlaceholderKeyCow<'data> as FromStr>::Err: Debug,
{
type Error = icu_pattern::PatternError;

fn try_from(elements: PluralElements<&'data str>) -> Result<Self, Self::Error> {
let make_pattern = |s: &&str| Pattern::<B, String>::from_str(s).map(|p| p.take_store());

Ok(Self {
strings: PluralElements::new(make_pattern(elements.other())?.as_str())
.with_zero_value(
Some(elements.zero())
.filter(|&e| e != elements.other())
.map(make_pattern)
.transpose()?
.as_deref(),
)
.with_one_value(
Some(elements.one())
.filter(|&e| e != elements.other())
.map(make_pattern)
.transpose()?
.as_deref(),
)
.with_two_value(
Some(elements.two())
.filter(|&e| e != elements.other())
.map(make_pattern)
.transpose()?
.as_deref(),
)
.with_few_value(
Some(elements.few())
.filter(|&e| e != elements.other())
.map(make_pattern)
.transpose()?
.as_deref(),
)
.with_many_value(
Some(elements.many())
.filter(|&e| e != elements.other())
.map(make_pattern)
.transpose()?
.as_deref(),
)
.with_explicit_zero_value(
elements
.explicit_zero()
.map(make_pattern)
.transpose()?
.as_deref(),
)
.with_explicit_one_value(
elements
.explicit_one()
.map(make_pattern)
.transpose()?
.as_deref(),
)
.into(),
_phantom: PhantomData,
})
}
pub future: PluralElementsPackedCow<'data, SinglePlaceholderPattern>,
}

pub(crate) struct ErasedRelativeTimeFormatV1Marker;
Expand Down
Loading