Skip to content

Commit 8d19b84

Browse files
authored
DateTime FFI and builder improvements (#6373)
1 parent b15d9e1 commit 8d19b84

File tree

11 files changed

+122
-75
lines changed

11 files changed

+122
-75
lines changed

components/datetime/src/builder.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,33 @@ impl FieldSetBuilder {
582582
}
583583
}
584584

585+
/// Builds a [`Combo`] for a zoned date.
586+
///
587+
/// An error will occur if incompatible fields or options were set in the builder.
588+
pub fn build_zoned_date(mut self) -> Result<ZonedDateFieldSet, BuilderError> {
589+
let zone_field_set = self.build_zone_without_checking_options()?;
590+
let date_field_set = self.build_date()?;
591+
Ok(date_field_set.zone(zone_field_set))
592+
}
593+
594+
/// Builds a [`Combo`] for a zoned time.
595+
///
596+
/// An error will occur if incompatible fields or options were set in the builder.
597+
pub fn build_zoned_time(mut self) -> Result<ZonedTimeFieldSet, BuilderError> {
598+
let zone_field_set = self.build_zone_without_checking_options()?;
599+
let time_field_set = self.build_time()?;
600+
Ok(time_field_set.zone(zone_field_set))
601+
}
602+
603+
/// Builds a [`Combo`] for a zoned date and time.
604+
///
605+
/// An error will occur if incompatible fields or options were set in the builder.
606+
pub fn build_zoned_date_and_time(mut self) -> Result<ZonedDateAndTimeFieldSet, BuilderError> {
607+
let zone_field_set = self.build_zone_without_checking_options()?;
608+
let datetime_field_set = self.build_date_and_time()?;
609+
Ok(datetime_field_set.zone(zone_field_set))
610+
}
611+
585612
/// Builds a [`CompositeFieldSet`].
586613
///
587614
/// An error will occur if incompatible fields or options were set in the builder.

components/datetime/src/dynamic.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,21 @@ impl GetField<CompositeFieldSet> for CompositeDateTimeFieldSet {
258258
}
259259
}
260260

261+
/// Type alias representing all possible date + time zone field sets.
262+
///
263+
/// This is a dynamic field set. For more information, see [`enums`](crate::fieldsets::enums).
264+
pub type ZonedDateFieldSet = Combo<DateFieldSet, ZoneFieldSet>;
265+
266+
/// Type alias representing all possible time + time zone field sets.
267+
///
268+
/// This is a dynamic field set. For more information, see [`enums`](crate::fieldsets::enums).
269+
pub type ZonedTimeFieldSet = Combo<TimeFieldSet, ZoneFieldSet>;
270+
271+
/// Type alias representing all possible date + time + time zone field sets.
272+
///
273+
/// This is a dynamic field set. For more information, see [`enums`](crate::fieldsets::enums).
274+
pub type ZonedDateAndTimeFieldSet = Combo<DateAndTimeFieldSet, ZoneFieldSet>;
275+
261276
/// An enum supporting all possible field sets and options.
262277
///
263278
/// This is a dynamic field set. For more information, see [`enums`](crate::fieldsets::enums).
@@ -275,11 +290,11 @@ pub enum CompositeFieldSet {
275290
/// Field set for a date and a time together.
276291
DateTime(DateAndTimeFieldSet),
277292
/// Field set for a date and a time zone together.
278-
DateZone(Combo<DateFieldSet, ZoneFieldSet>),
293+
DateZone(ZonedDateFieldSet),
279294
/// Field set for a time and a time zone together.
280-
TimeZone(Combo<TimeFieldSet, ZoneFieldSet>),
295+
TimeZone(ZonedTimeFieldSet),
281296
/// Field set for a date, a time, and a time zone together.
282-
DateTimeZone(Combo<DateAndTimeFieldSet, ZoneFieldSet>),
297+
DateTimeZone(ZonedDateAndTimeFieldSet),
283298
}
284299

285300
macro_rules! first {

components/datetime/src/fieldsets.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ macro_rules! impl_zone_combo_helpers {
305305
impl_combo_get_field!($type, $composite, $enum, zone::GenericShort);
306306
impl_combo_get_field!($type, $composite, $enum, zone::Location);
307307
impl_combo_get_field!($type, $composite, $enum, zone::ExemplarCity);
308+
impl_combo_get_field!($type, $composite, $enum, ZoneFieldSet);
308309
};
309310
}
310311

ffi/capi/src/datetime_helpers.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ where
4343
Zone: DateTimeMarkers + ZoneMarkers,
4444
<Zone as DateTimeMarkers>::Z: ZoneMarkers,
4545
Combo<DateFieldSet, Zone>: DateTimeNamesFrom<DateFieldSet>,
46-
Combo<DateFieldSet, ZoneFieldSet>: DateTimeNamesFrom<Combo<DateFieldSet, Zone>>,
46+
ZonedDateFieldSet: DateTimeNamesFrom<Combo<DateFieldSet, Zone>>,
4747
{
4848
let prefs = (&locale.0).into();
4949
let mut names = DateTimeNames::from_formatter(prefs, formatter.clone())
@@ -97,7 +97,7 @@ where
9797
Zone: DateTimeMarkers + ZoneMarkers,
9898
<Zone as DateTimeMarkers>::Z: ZoneMarkers,
9999
Combo<DateAndTimeFieldSet, Zone>: DateTimeNamesFrom<CompositeDateTimeFieldSet>,
100-
CompositeFieldSet: DateTimeNamesFrom<Combo<DateAndTimeFieldSet, Zone>>,
100+
ZonedDateAndTimeFieldSet: DateTimeNamesFrom<Combo<DateAndTimeFieldSet, Zone>>,
101101
{
102102
let prefs = (&locale.0).into();
103103
let mut names = DateTimeNames::from_formatter(prefs, formatter.clone())
@@ -151,7 +151,7 @@ where
151151
Zone: DateTimeMarkers + ZoneMarkers,
152152
<Zone as DateTimeMarkers>::Z: ZoneMarkers,
153153
Combo<DateFieldSet, Zone>: DateTimeNamesFrom<DateFieldSet>,
154-
Combo<DateFieldSet, ZoneFieldSet>: DateTimeNamesFrom<Combo<DateFieldSet, Zone>>,
154+
ZonedDateFieldSet: DateTimeNamesFrom<Combo<DateFieldSet, Zone>>,
155155
{
156156
let prefs = (&locale.0).into();
157157
let mut names = FixedCalendarDateTimeNames::from_formatter(prefs, formatter.clone())
@@ -205,7 +205,7 @@ where
205205
Zone: DateTimeMarkers + ZoneMarkers,
206206
<Zone as DateTimeMarkers>::Z: ZoneMarkers,
207207
Combo<DateAndTimeFieldSet, Zone>: DateTimeNamesFrom<CompositeDateTimeFieldSet>,
208-
CompositeFieldSet: DateTimeNamesFrom<Combo<DateAndTimeFieldSet, Zone>>,
208+
ZonedDateAndTimeFieldSet: DateTimeNamesFrom<Combo<DateAndTimeFieldSet, Zone>>,
209209
{
210210
let prefs = (&locale.0).into();
211211
let mut names = FixedCalendarDateTimeNames::from_formatter(prefs, formatter.clone())

ffi/capi/src/zoned_date_formatter.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ pub mod ffi {
3636
#[diplomat::rust_link(icu::datetime::DateTimeFormatter, Typedef)]
3737
pub struct ZonedDateFormatter(
3838
pub icu_datetime::DateTimeFormatter<
39-
icu_datetime::fieldsets::Combo<
40-
icu_datetime::fieldsets::enums::DateFieldSet,
41-
icu_datetime::fieldsets::enums::ZoneFieldSet,
42-
>
39+
icu_datetime::fieldsets::enums::ZonedDateFieldSet
4340
>,
4441
);
4542

@@ -515,10 +512,7 @@ pub mod ffi {
515512
pub struct ZonedDateFormatterGregorian(
516513
pub icu_datetime::FixedCalendarDateTimeFormatter<
517514
Gregorian,
518-
icu_datetime::fieldsets::Combo<
519-
icu_datetime::fieldsets::enums::DateFieldSet,
520-
icu_datetime::fieldsets::enums::ZoneFieldSet,
521-
>
515+
icu_datetime::fieldsets::enums::ZonedDateFieldSet
522516
>,
523517
);
524518

ffi/capi/src/zoned_date_time_formatter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub mod ffi {
3636
#[diplomat::rust_link(icu::datetime::DateTimeFormatter, Typedef)]
3737
pub struct ZonedDateTimeFormatter(
3838
pub icu_datetime::DateTimeFormatter<
39-
icu_datetime::fieldsets::enums::CompositeFieldSet
39+
icu_datetime::fieldsets::enums::ZonedDateAndTimeFieldSet
4040
>,
4141
);
4242

@@ -514,7 +514,7 @@ pub mod ffi {
514514
pub struct ZonedDateTimeFormatterGregorian(
515515
pub icu_datetime::FixedCalendarDateTimeFormatter<
516516
Gregorian,
517-
icu_datetime::fieldsets::enums::CompositeFieldSet
517+
icu_datetime::fieldsets::enums::ZonedDateAndTimeFieldSet
518518
>,
519519
);
520520

ffi/capi/src/zoned_time_formatter.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ pub mod ffi {
3636
pub struct ZonedTimeFormatter(
3737
pub icu_datetime::FixedCalendarDateTimeFormatter<
3838
(),
39-
icu_datetime::fieldsets::Combo<
40-
icu_datetime::fieldsets::enums::TimeFieldSet,
41-
icu_datetime::fieldsets::enums::ZoneFieldSet,
42-
>
39+
icu_datetime::fieldsets::enums::ZonedTimeFieldSet
4340
>,
4441
);
4542

ffi/capi/tests/missing_apis.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ icu::datetime::fieldsets::builder::FieldSetBuilder::build_date#FnInStruct
7070
icu::datetime::fieldsets::builder::FieldSetBuilder::build_date_and_time#FnInStruct
7171
icu::datetime::fieldsets::builder::FieldSetBuilder::build_time#FnInStruct
7272
icu::datetime::fieldsets::builder::FieldSetBuilder::build_zone#FnInStruct
73+
icu::datetime::fieldsets::builder::FieldSetBuilder::build_zoned_date#FnInStruct
74+
icu::datetime::fieldsets::builder::FieldSetBuilder::build_zoned_date_and_time#FnInStruct
75+
icu::datetime::fieldsets::builder::FieldSetBuilder::build_zoned_time#FnInStruct
7376
icu::datetime::fieldsets::builder::FieldSetBuilder::new#FnInStruct
7477
icu::datetime::fieldsets::builder::ZoneStyle#Enum
7578
icu::datetime::fieldsets::enums::CalendarPeriodFieldSet#Enum
@@ -84,6 +87,9 @@ icu::datetime::fieldsets::enums::DateFieldSet::zone#FnInEnum
8487
icu::datetime::fieldsets::enums::TimeFieldSet#Enum
8588
icu::datetime::fieldsets::enums::TimeFieldSet::zone#FnInEnum
8689
icu::datetime::fieldsets::enums::ZoneFieldSet#Enum
90+
icu::datetime::fieldsets::enums::ZonedDateAndTimeFieldSet#Typedef
91+
icu::datetime::fieldsets::enums::ZonedDateFieldSet#Typedef
92+
icu::datetime::fieldsets::enums::ZonedTimeFieldSet#Typedef
8793
icu::datetime::fieldsets::zone::ExemplarCity#Struct
8894
icu::datetime::fieldsets::zone::GenericLong#Struct
8995
icu::datetime::fieldsets::zone::GenericShort#Struct

tools/make/codegen/src/capi_datetime.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,43 @@ impl ConsumedOptions {
3535
}
3636
}
3737

38+
#[derive(Debug, Copy, Clone)]
39+
enum ConstructorType {
40+
CompiledData,
41+
WithProvider,
42+
}
43+
44+
impl ConstructorType {
45+
pub const VALUES: &'static [Self] = &[Self::CompiledData, Self::WithProvider];
46+
pub fn is_with_provider(self) -> bool {
47+
matches!(self, Self::WithProvider)
48+
}
49+
pub fn prefix(self) -> &'static str {
50+
match self {
51+
Self::CompiledData => "include_",
52+
Self::WithProvider => "load_",
53+
}
54+
}
55+
pub fn suffix_ffi(self) -> &'static str {
56+
match self {
57+
Self::CompiledData => "",
58+
Self::WithProvider => "_with_provider",
59+
}
60+
}
61+
pub fn suffix_rust(self) -> &'static str {
62+
match self {
63+
Self::CompiledData => "",
64+
Self::WithProvider => "_with_buffer_provider",
65+
}
66+
}
67+
pub fn cargo_feature(self) -> &'static str {
68+
match self {
69+
Self::CompiledData => "compiled_data",
70+
Self::WithProvider => "buffer_provider",
71+
}
72+
}
73+
}
74+
3875
#[derive(Copy, Clone)]
3976
enum FormatterFlavor {
4077
Date,

tools/make/codegen/templates/datetime_formatter.rs.jinja

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,17 @@ pub mod ffi {
5757

5858
impl {{ ffi_type }} {
5959
{%- for variant in variants %}
60-
{%- for is_with_provider in [false, true] %}
61-
{%- let ctor_suffix_ffi %}
62-
{%- let ctor_suffix_rust %}
63-
{%- let cargo_feature %}
60+
{%- for ctor in ConstructorType::VALUES %}
6461
{%- let named_constructor %}
6562
{%- let named_constructor_full %}
66-
{%- if is_with_provider %}
63+
{%- if ctor.is_with_provider() %}
6764
{%- if variant.is_only_constructor() %}
6865
{%- let named_constructor = "with_provider".to_string() %}
6966
{%- let named_constructor_full = "create_with_provider".to_string() %}
7067
{%- else %}
7168
{%- let named_constructor = format!("{}_with_provider", variant.name_lower()) %}
7269
{%- let named_constructor_full = format!("create_{}_with_provider", variant.name_lower()) %}
7370
{%- endif %}
74-
{%- let ctor_suffix_ffi = "with_provider" %}
75-
{%- let ctor_suffix_rust = "_with_buffer_provider" %}
76-
{%- let cargo_feature = "buffer_provider" %}
7771
{%- else %}
7872
{%- if variant.is_only_constructor() %}
7973
{%- let named_constructor = "".to_string() %}
@@ -82,9 +76,6 @@ pub mod ffi {
8276
{%- let named_constructor = format!("{}", variant.name_lower()) %}
8377
{%- let named_constructor_full = format!("create_{}", variant.name_lower()) %}
8478
{%- endif %}
85-
{%- let ctor_suffix_ffi = "" %}
86-
{%- let ctor_suffix_rust = "" %}
87-
{%- let cargo_feature = "compiled_data" %}
8879
{%- endif %}
8980
{%- if named_constructor == "" %}
9081
#[diplomat::attr(supports = fallible_constructors, constructor)]
@@ -105,12 +96,12 @@ pub mod ffi {
10596
#[diplomat::rust_link(icu::datetime::fieldsets::{{ variant.name_upper() }}::short, FnInStruct, hidden)]
10697
#[diplomat::rust_link(icu::datetime::fieldsets::{{ variant.name_upper() }}::medium, FnInStruct, hidden)]
10798
#[diplomat::rust_link(icu::datetime::fieldsets::{{ variant.name_upper() }}::long, FnInStruct, hidden)]
108-
{%- if variant.is_default_constructor() && !is_with_provider %}
99+
{%- if variant.is_default_constructor() && !ctor.is_with_provider() %}
109100
#[diplomat::demo(default_constructor)]
110101
{%- endif %}
111-
#[cfg(feature = "{{ cargo_feature }}")]
102+
#[cfg(feature = "{{ ctor.cargo_feature() }}")]
112103
pub fn {{ named_constructor_full }}(
113-
{%- if is_with_provider %}
104+
{%- if ctor.is_with_provider() %}
114105
provider: &DataProvider,
115106
{%- endif %}
116107
locale: &Locale,
@@ -142,8 +133,8 @@ pub mod ffi {
142133
Ok(Box::new(Self(
143134
icu_datetime
144135
::{{ formatter_kind.rust_type() }}
145-
::try_new{{ ctor_suffix_rust }}(
146-
{%- if is_with_provider %}
136+
::try_new{{ ctor.suffix_rust() }}(
137+
{%- if ctor.is_with_provider() %}
147138
provider.get()?,
148139
{%- endif %}
149140
prefs,

0 commit comments

Comments
 (0)