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

zbraniecki / icu4x / 13958601093

19 Mar 2025 04:17PM UTC coverage: 74.164% (-1.5%) from 75.71%
13958601093

push

github

web-flow
Clean up properties docs (#6315)

58056 of 78281 relevant lines covered (74.16%)

819371.32 hits per line

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

92.0
/components/datetime/src/pattern/pattern.rs
1
// This file is part of ICU4X. For terms of use, please see the file
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
use core::str::FromStr;
6

7
use writeable::{impl_display_with_writeable, Writeable};
8

9
use crate::provider::pattern::{runtime, PatternError, PatternItem};
10
use crate::size_test_macro::size_test;
11

12
size_test!(DateTimePattern, date_time_pattern_size, 32);
13

14
/// A pattern for formatting a datetime in a calendar.
15
///
16
/// ❗ This type forgoes most internationalization functionality of the datetime crate.
17
/// It assumes that the pattern is already localized for the customer's locale. Most clients
18
/// should use [`DateTimeFormatter`] instead of directly formatting with patterns.
19
///
20
/// There are two ways to make one of these:
21
///
22
/// 1. From a custom pattern string: [`DateTimePattern::try_from_pattern_str`]
23
/// 2. From a formatted datetime: [`FormattedDateTime::pattern`]
24
///
25
/// Things you can do with one of these:
26
///
27
/// 1. Use it to directly format a datetime via [`FixedCalendarDateTimeNames`]
28
/// 2. Convert it to a string pattern via [`Writeable`]
29
/// 3. Get the resolved components
30
#[doc = date_time_pattern_size!()]
31
///
32
/// # Examples
33
///
34
/// Create a pattern from a custom string and compare it to one from data,
35
/// then check the resolved components:
36
///
37
/// ```
38
/// use icu::calendar::Gregorian;
39
/// use icu::datetime::fieldsets::YMD;
40
/// use icu::datetime::input::Date;
41
/// use icu::datetime::pattern::DateTimePattern;
42
/// use icu::datetime::provider::fields::components;
43
/// use icu::datetime::FixedCalendarDateTimeFormatter;
44
/// use icu::locale::locale;
45
/// use writeable::assert_writeable_eq;
46
///
47
/// // Create the pattern from a string:
48
/// let pattern_str = "d MMM y";
49
/// let custom_pattern =
50
///     DateTimePattern::try_from_pattern_str(pattern_str).unwrap();
51
/// assert_writeable_eq!(custom_pattern, pattern_str);
52
///
53
/// // Load data that resolves to the same pattern:
54
/// let data_pattern = FixedCalendarDateTimeFormatter::<Gregorian, _>::try_new(
55
///     locale!("es-MX").into(),
56
///     YMD::medium(),
57
/// )
58
/// .unwrap()
59
/// // The pattern can depend on the datetime being formatted.
60
/// .format(&Date::try_new_gregorian(2024, 1, 1).unwrap())
61
/// .pattern();
62
/// assert_writeable_eq!(data_pattern, pattern_str);
63
/// assert_eq!(custom_pattern, data_pattern);
64
///
65
/// // Check the resolved components:
66
/// let mut expected_components_bag = components::Bag::default();
67
/// expected_components_bag.year = Some(components::Year::Numeric);
68
/// expected_components_bag.month = Some(components::Month::Short);
69
/// expected_components_bag.day = Some(components::Day::NumericDayOfMonth);
70
/// let actual_components_bag = components::Bag::from(&data_pattern);
71
/// assert_eq!(actual_components_bag, expected_components_bag);
72
/// ```
73
///
74
/// Check the hour cycle of a resolved pattern:
75
///
76
/// ```
77
/// use icu::datetime::fieldsets::T;
78
/// use icu::datetime::input::Time;
79
/// use icu::datetime::pattern::DateTimePattern;
80
/// use icu::datetime::provider::fields::components;
81
/// use icu::datetime::NoCalendarFormatter;
82
/// use icu::locale::locale;
83
/// use icu::locale::preferences::extensions::unicode::keywords::HourCycle;
84
/// use writeable::assert_writeable_eq;
85
///
86
/// let pattern =
87
///     NoCalendarFormatter::try_new(locale!("es-MX").into(), T::medium())
88
///         .unwrap()
89
///         // The pattern can depend on the datetime being formatted.
90
///         .format(&Time::try_new(12, 0, 0, 0).unwrap())
91
///         .pattern();
92
///
93
/// assert_writeable_eq!(pattern, "hh:mm:ss a");
94
///
95
/// // Get the hour cycle from the resolved components:
96
/// let components = components::Bag::from(&pattern);
97
/// assert_eq!(components.hour_cycle, Some(HourCycle::H12));
98
/// ```
99
///
100
/// [`DateTimeFormatter`]: crate::DateTimeFormatter
101
/// [`FormattedDateTime::pattern`]: crate::FormattedDateTime::pattern
102
/// [`FixedCalendarDateTimeNames`]: crate::pattern::FixedCalendarDateTimeNames
103
#[derive(Debug)]
×
104
pub struct DateTimePattern {
105
    pattern: runtime::Pattern<'static>,
×
106
}
107

108
impl DateTimePattern {
109
    /// Creates a [`DateTimePattern`] from a pattern string.
110
    ///
111
    /// For more details on the syntax, see UTS 35:
112
    /// <https://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns>
113
    pub fn try_from_pattern_str(pattern_str: &str) -> Result<Self, PatternError> {
312✔
114
        let pattern = runtime::Pattern::from_str(pattern_str)?;
312✔
115
        Ok(Self { pattern })
312✔
116
    }
312✔
117

118
    #[doc(hidden)] // TODO(#4467): Internal API
119
    pub fn from_runtime_pattern(pattern: runtime::Pattern<'static>) -> Self {
324✔
120
        Self { pattern }
324✔
121
    }
324✔
122

123
    pub(crate) fn iter_items(&self) -> impl Iterator<Item = PatternItem> + '_ {
258✔
124
        self.pattern.items.iter()
258✔
125
    }
258✔
126

127
    pub(crate) fn as_borrowed(&self) -> DateTimePatternBorrowed {
754✔
128
        DateTimePatternBorrowed(&self.pattern)
129
    }
754✔
130
}
131

132
impl FromStr for DateTimePattern {
133
    type Err = PatternError;
134
    fn from_str(s: &str) -> Result<Self, Self::Err> {
56✔
135
        Self::try_from_pattern_str(s)
56✔
136
    }
56✔
137
}
138

139
// Check equality on the borrowed variant since it flattens the difference
140
// between the three `Single` pattern variants, which is not public-facing
141
impl PartialEq for DateTimePattern {
142
    fn eq(&self, other: &Self) -> bool {
213✔
143
        self.as_borrowed().eq(&other.as_borrowed())
213✔
144
    }
213✔
145
}
146

147
impl Eq for DateTimePattern {}
148

149
impl Writeable for DateTimePattern {
150
    fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result {
22✔
151
        self.pattern.write_to(sink)
22✔
152
    }
22✔
153
}
154

155
impl_display_with_writeable!(DateTimePattern);
156

157
// Not clear if this needs to be public. For now, make it private.
158
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
426✔
159
pub(crate) struct DateTimePatternBorrowed<'a>(pub(crate) &'a runtime::Pattern<'a>);
213✔
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

© 2026 Coveralls, Inc