From a6529b89a25af9a58c0a2ca761f0c9180d5b3d40 Mon Sep 17 00:00:00 2001 From: Kart Date: Mon, 8 Jul 2024 10:29:50 -0400 Subject: [PATCH] Create `DigitalDurationDataV1` (#5186) --- components/experimental/src/duration/mod.rs | 2 + .../src/duration/provider/digital.rs | 64 +++++++++++++++++++ .../experimental/src/duration/provider/mod.rs | 10 +++ provider/source/src/cldr_serde/units/data.rs | 21 ++++++ 4 files changed, 97 insertions(+) create mode 100644 components/experimental/src/duration/provider/digital.rs create mode 100644 components/experimental/src/duration/provider/mod.rs diff --git a/components/experimental/src/duration/mod.rs b/components/experimental/src/duration/mod.rs index 57ec74e6192..ec21ea1a710 100644 --- a/components/experimental/src/duration/mod.rs +++ b/components/experimental/src/duration/mod.rs @@ -8,6 +8,8 @@ mod duration; mod formatter; +pub mod provider; + pub mod options; pub use duration::{Duration, DurationSign}; diff --git a/components/experimental/src/duration/provider/digital.rs b/components/experimental/src/duration/provider/digital.rs new file mode 100644 index 00000000000..edb46edcd68 --- /dev/null +++ b/components/experimental/src/duration/provider/digital.rs @@ -0,0 +1,64 @@ +// 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)] + +//! Provider structs for digital data. + +use alloc::borrow::Cow; +use alloc::string::{String, ToString}; +use core::str::FromStr; + +use displaydoc::Display; +use icu_provider::prelude::*; + +#[icu_provider::data_struct(DigitalDurationDataV1Marker = "duration/digital@1")] +#[derive(Debug, Clone, PartialEq)] +#[cfg_attr( + feature = "datagen", + derive(serde::Serialize, databake::Bake), + databake(path = icu_experimental::duration::provider) +)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] + +/// A struct containing digital duration data (durationUnit-type-* patterns). +pub struct DigitalDurationDataV1<'data> { + /// The separator between the hour, minute, and second fields. + #[cfg_attr(feature = "serde", serde(borrow))] + separator: Cow, + + /// The number of digits to pad the hour field with. + hour_padding: u8, +} + +/// Unknown time pattern: {0} +#[derive(Debug, Display)] +pub struct UnknownPatternError(String); + +impl<'data> FromStr for DigitalDurationDataV1<'data> { + type Err = UnknownPatternError; + + fn from_str(s: &str) -> Result { + match s { + "hh:mm:ss" => Ok(DigitalDurationDataV1 { + separator: ":".into(), + hour_padding: 2, + }), + "h:mm:ss" => Ok(DigitalDurationDataV1 { + separator: ":".into(), + hour_padding: 1, + }), + "h.mm.ss" => Ok(DigitalDurationDataV1 { + separator: ".".into(), + hour_padding: 1, + }), + "h,mm,ss" => Ok(DigitalDurationDataV1 { + separator: ",".into(), + hour_padding: 1, + }), + _ => Err(UnknownPatternError(s.to_string())), + } + } +} diff --git a/components/experimental/src/duration/provider/mod.rs b/components/experimental/src/duration/provider/mod.rs new file mode 100644 index 00000000000..24d4d96662a --- /dev/null +++ b/components/experimental/src/duration/provider/mod.rs @@ -0,0 +1,10 @@ +// 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 ). + +//! Data provider struct definitions for this ICU4X component. +//! +//! Read more about data providers: [`icu_provider`] + +pub mod digital; +pub use digital::{DigitalDurationDataV1, DigitalDurationDataV1Marker}; diff --git a/provider/source/src/cldr_serde/units/data.rs b/provider/source/src/cldr_serde/units/data.rs index 61cb3046d9e..d367f8e1588 100644 --- a/provider/source/src/cldr_serde/units/data.rs +++ b/provider/source/src/cldr_serde/units/data.rs @@ -62,6 +62,24 @@ pub(crate) struct Patterns { pub(crate) other_compound_unit_pattern1: Option, } +#[derive(PartialEq, Debug, Deserialize)] +pub struct DurationUnit { + #[serde(rename = "durationUnitPattern")] + pub(crate) pat: String, + #[serde(rename = "durationUnitPattern-alt-variant")] + pub(crate) alt_pat: Option, +} + +#[derive(PartialEq, Debug, Deserialize)] +pub struct DurationUnits { + #[serde(rename = "durationUnit-type-hm")] + pub hm: DurationUnit, + #[serde(rename = "durationUnit-type-hms")] + pub hms: DurationUnit, + #[serde(rename = "durationUnit-type-ms")] + pub ms: DurationUnit, +} + // TODO: replace Value with specific structs #[derive(PartialEq, Debug, Deserialize)] pub(crate) struct UnitsData { @@ -70,6 +88,9 @@ pub(crate) struct UnitsData { pub(crate) short: BTreeMap, pub(crate) narrow: BTreeMap, + + #[serde(flatten)] + pub(crate) duration: DurationUnits, } #[derive(PartialEq, Debug, Deserialize)]