• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zbraniecki / icu4x / 6815798908

09 Nov 2023 05:17PM UTC coverage: 72.607% (-2.4%) from 75.01%
6815798908

push

github

web-flow
Implement `Any/BufferProvider` for some smart pointers (#4255)

Allows storing them as a `Box<dyn Any/BufferProvider>` without using a
wrapper type that implements the trait.

44281 of 60987 relevant lines covered (72.61%)

201375.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

3.23
/components/datetime/src/lib.rs
1
// This file is part of ICU4X. For terms of use, please see the file
1✔
2
// called LICENSE at the top level of the ICU4X source tree
3
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4

5
//! Formatting date and time.
6
//!
7
//! This module is published as its own crate ([`icu_datetime`](https://docs.rs/icu_datetime/latest/icu_datetime/))
8
//! and as part of the [`icu`](https://docs.rs/icu/latest/icu/) crate. See the latter for more details on the ICU4X project.
9
//!
10
//! [`TypedDateTimeFormatter`] and [`DateTimeFormatter`] are the main types of the component. They accepts a set of arguments which
11
//! allow it to collect necessary data from the [data provider], and once instantiated, can be
12
//! used to quickly format any date and time provided. There are variants of these types that can format greater or fewer components,
13
//! including [`TypedDateFormatter`] & [`DateFormatter`], [`TypedZonedDateTimeFormatter`] & [`ZonedDateTimeFormatter`], [`TimeFormatter`],
14
//! and [`TimeZoneFormatter`]
15
//!
16
//! These formatters work with types from the [`calendar`] module, like [`Date`], [`DateTime`], and [`Time`],
17
//! and [`timezone::CustomTimeZone`], however other types may be used provided they implement the traits from the [`input`] module.
18
//!
19
//! Each instance of a date-related formatter (i.e. not [`TimeFormatter`] or [`TimeZoneFormatter`]
20
//! is associated with a particular [`Calendar`].
21
//! The "Typed" vs untyped formatter distinction is to help with this. For example, if you know at compile time that you
22
//! will only be formatting Gregorian dates, you can use [`TypedDateTimeFormatter<Gregorian>`](TypedDateTimeFormatter) and the
23
//! APIs will make sure that only Gregorian [`DateTime`]s are used with the calendar. On the other hand, if you want to be able to select
24
//! the calendar at runtime, you can use [`DateTimeFormatter`] with the calendar specified in the locale, and use it with
25
//! [`DateTime`],[`AnyCalendar`]. These formatters still require dates associated
26
//! with the appropriate calendar (though they will convert ISO dates to the calendar if provided), they just do not force the
27
//! programmer to pick the calendar at compile time.
28
//!
29
//!
30
//! # Examples
31
//!
32
//! ```
33
//! use icu::calendar::{DateTime, Gregorian};
34
//! use icu::datetime::{
35
//!     options::length, DateTimeFormatter, DateTimeFormatterOptions,
36
//!     TypedDateTimeFormatter,
37
//! };
38
//! use icu::locid::{locale, Locale};
39
//! use std::str::FromStr;
40
//! use writeable::assert_writeable_eq;
41
//!
42
//! // See the next code example for a more ergonomic example with .into().
43
//! let options =
44
//!     DateTimeFormatterOptions::Length(length::Bag::from_date_time_style(
45
//!         length::Date::Medium,
46
//!         length::Time::Short,
47
//!     ));
48
//!
49
//! // You can work with a formatter that can select the calendar at runtime:
50
//! let locale = Locale::from_str("en-u-ca-gregory").unwrap();
51
//! let dtf = DateTimeFormatter::try_new(&locale.into(), options.clone())
52
//!     .expect("Failed to create DateTimeFormatter instance.");
53
//!
54
//! // Or one that selects a calendar at compile time:
55
//! let typed_dtf = TypedDateTimeFormatter::<Gregorian>::try_new(
56
//!     &locale!("en").into(),
57
//!     options,
58
//! )
59
//! .expect("Failed to create TypedDateTimeFormatter instance.");
60
//!
61
//! let typed_date =
62
//!     DateTime::try_new_gregorian_datetime(2020, 9, 12, 12, 34, 28).unwrap();
63
//! // prefer using ISO dates with DateTimeFormatter
64
//! let date = typed_date.to_iso().to_any();
65
//!
66
//! let formatted_date = dtf.format(&date).expect("Calendars should match");
67
//! let typed_formatted_date = typed_dtf.format(&typed_date);
68
//!
69
//! assert_writeable_eq!(formatted_date, "Sep 12, 2020, 12:34 PM");
70
//! assert_writeable_eq!(typed_formatted_date, "Sep 12, 2020, 12:34 PM");
71
//!
72
//! let formatted_date_string =
73
//!     dtf.format_to_string(&date).expect("Calendars should match");
74
//! let typed_formatted_date_string = typed_dtf.format_to_string(&typed_date);
75
//!
76
//! assert_eq!(formatted_date_string, "Sep 12, 2020, 12:34 PM");
77
//! assert_eq!(typed_formatted_date_string, "Sep 12, 2020, 12:34 PM");
78
//! ```
79
//!
80
//! The options can be created more ergonomically using the `Into` trait to automatically
81
//! convert a [`options::length::Bag`] into a [`DateTimeFormatterOptions::Length`].
82
//!
83
//! ```
84
//! use icu::calendar::Gregorian;
85
//! use icu::datetime::{
86
//!     options::length, DateTimeFormatterOptions, TypedDateTimeFormatter,
87
//! };
88
//! use icu::locid::locale;
89
//! let options = length::Bag::from_date_time_style(
90
//!     length::Date::Medium,
91
//!     length::Time::Short,
92
//! )
93
//! .into();
94
//!
95
//! let dtf = TypedDateTimeFormatter::<Gregorian>::try_new(
96
//!     &locale!("en").into(),
97
//!     options,
98
//! );
99
//! ```
100
//!
101
//! At the moment, the crate provides only options using the [`Length`] bag, but in the future,
102
//! we expect to add more ways to customize the output, like skeletons, and components.
103
//!
104
//! [data provider]: icu_provider
105
//! [`ICU4X`]: ../icu/index.html
106
//! [`Length`]: options::length
107
//! [`DateTime`]: calendar::{DateTime}
108
//! [`Date`]: calendar::{Date}
109
//! [`Time`]: calendar::types::{Time}
110
//! [`Calendar`]: calendar::{Calendar}
111
//! [`AnyCalendar`]: calendar::any_calendar::{AnyCalendar}
112
//! [`timezone::CustomTimeZone`]: icu::timezone::{CustomTimeZone}
113
//! [`TimeZoneFormatter`]: time_zone::TimeZoneFormatter
114

115
// https://github.com/unicode-org/icu4x/blob/main/docs/process/boilerplate.md#library-annotations
116
#![cfg_attr(not(any(test, feature = "std")), no_std)]
117
#![cfg_attr(
118
    not(test),
119
    deny(
120
        clippy::indexing_slicing,
121
        clippy::unwrap_used,
122
        clippy::expect_used,
123
        clippy::panic,
124
        clippy::exhaustive_structs,
125
        clippy::exhaustive_enums,
126
        missing_debug_implementations,
127
    )
128
)]
129
#![warn(missing_docs)]
130

131
extern crate alloc;
132

133
mod calendar;
134
mod datetime;
135
mod error;
136
pub mod fields;
137
mod format;
138
pub mod input;
139
pub mod options;
140
#[doc(hidden)]
141
pub mod pattern;
142
pub mod provider;
143
pub(crate) mod raw;
144
#[doc(hidden)]
145
#[allow(clippy::exhaustive_structs, clippy::exhaustive_enums)] // private-ish module
146
#[cfg(any(feature = "datagen", feature = "experimental"))]
147
pub mod skeleton;
148
pub mod time_zone;
149
mod zoned_datetime;
150

151
mod any;
152

153
pub use any::{DateFormatter, DateTimeFormatter, ZonedDateTimeFormatter};
154
pub use calendar::CldrCalendar;
155
pub use datetime::{TimeFormatter, TypedDateFormatter, TypedDateTimeFormatter};
156
pub use error::DateTimeError;
157
pub use format::datetime::FormattedDateTime;
158
pub use format::time_zone::FormattedTimeZone;
159
pub use format::zoned_datetime::FormattedZonedDateTime;
160
pub use options::DateTimeFormatterOptions;
161
pub use zoned_datetime::TypedZonedDateTimeFormatter;
162

163
#[doc(no_inline)]
164
pub use DateTimeError as Error;
165

166
#[cfg(test)]
167
mod tests {
168
    use super::*;
169
    use core::mem::size_of;
170
    use icu_calendar::week::WeekCalculator;
171
    use icu_calendar::Gregorian;
172
    use icu_decimal::FixedDecimalFormatter;
173
    use icu_plurals::PluralRules;
174
    use icu_provider::prelude::*;
175
    use icu_timezone::CustomTimeZone;
176
    use provider::calendar::patterns::GenericPatternV1Marker;
177
    use provider::calendar::patterns::PatternPluralsFromPatternsV1Marker;
178
    use provider::calendar::ErasedDateSymbolsV1Marker;
179
    use provider::calendar::TimeSymbolsV1Marker;
180
    use provider::time_zones::ExemplarCitiesV1Marker;
181
    use provider::time_zones::MetazoneGenericNamesLongV1Marker;
182
    use provider::time_zones::MetazoneGenericNamesShortV1Marker;
183
    use provider::time_zones::MetazoneSpecificNamesLongV1Marker;
184
    use provider::time_zones::MetazoneSpecificNamesShortV1Marker;
185
    use provider::time_zones::TimeZoneFormatsV1Marker;
186
    use time_zone::TimeZoneDataPayloads;
187
    use time_zone::TimeZoneFormatter;
188
    use time_zone::TimeZoneFormatterUnit;
189

190
    /// Checks that the size of the type is one of the given sizes.
191
    /// The size might differ across Rust versions or channels.
192
    macro_rules! check_size_of {
193
        ($sizes:pat, $type:path) => {
194
            assert!(
195
                matches!(size_of::<$type>(), $sizes),
196
                concat!(stringify!($type), " is of size {}"),
197
                size_of::<$type>()
198
            );
199
        };
200
    }
201

202
    #[test]
203
    // TODO(#3413): Delete this test when no longer needed.
204
    #[ignore] // Changes too much across nightlies.
205
    fn check_sizes() {
×
206
        check_size_of!(4616, DateFormatter);
×
207
        check_size_of!(5488, DateTimeFormatter);
×
208
        check_size_of!(6536, ZonedDateTimeFormatter);
×
209
        check_size_of!(1344, TimeFormatter);
×
210
        check_size_of!(1048, TimeZoneFormatter);
×
211
        check_size_of!(4568, TypedDateFormatter::<Gregorian>);
×
212
        check_size_of!(5440, TypedDateTimeFormatter::<Gregorian>);
×
213

214
        check_size_of!(88, DateTimeError);
×
215
        check_size_of!(184, FormattedDateTime);
×
216
        check_size_of!(16, FormattedTimeZone::<CustomTimeZone>);
×
217
        check_size_of!(168, FormattedZonedDateTime);
×
218

219
        if cfg!(feature = "experimental") {
220
            check_size_of!(13, DateTimeFormatterOptions);
×
221
        }
222

223
        type DP<M> = DataPayload<M>;
224
        check_size_of!(216, DP::<PatternPluralsFromPatternsV1Marker>);
×
225
        check_size_of!(1032 | 912, DP::<TimeSymbolsV1Marker>);
×
226
        check_size_of!(40, DP::<GenericPatternV1Marker>);
×
227
        check_size_of!(216, DP::<PatternPluralsFromPatternsV1Marker>);
×
228
        check_size_of!(5064 | 3912, DP::<ErasedDateSymbolsV1Marker>);
×
229
        check_size_of!(232 | 240, DP::<TimeZoneFormatsV1Marker>);
×
230
        check_size_of!(64, DP::<ExemplarCitiesV1Marker>);
×
231
        check_size_of!(120 | 112, DP::<MetazoneGenericNamesLongV1Marker>);
×
232
        check_size_of!(120 | 112, DP::<MetazoneGenericNamesShortV1Marker>);
×
233
        check_size_of!(216 | 208, DP::<MetazoneSpecificNamesLongV1Marker>);
×
234
        check_size_of!(216 | 208, DP::<MetazoneSpecificNamesShortV1Marker>);
×
235
        check_size_of!(2, WeekCalculator);
×
236
        check_size_of!(176, PluralRules);
×
237
        check_size_of!(256 | 216, FixedDecimalFormatter);
×
238
        check_size_of!(1024 | 936, TimeZoneDataPayloads);
×
239
        check_size_of!(3, TimeZoneFormatterUnit);
×
240
    }
×
241
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc