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

zbraniecki / icu4x / 9457158389

10 Jun 2024 11:45PM UTC coverage: 75.174% (+0.05%) from 75.121%
9457158389

push

github

web-flow
Add constructing TinyAsciiStr from utf16 (#5025)

Introduces TinyAsciiStr constructors from utf16 and converges on the
consensus from #4931.

---------

Co-authored-by: Robert Bastian <4706271+robertbastian@users.noreply.github.com>

65 of 82 new or added lines in 14 files covered. (79.27%)

3441 existing lines in 141 files now uncovered.

52850 of 70304 relevant lines covered (75.17%)

563298.06 hits per line

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

80.65
/components/datetime/src/pattern/hour_cycle.rs
1
// This file is part of ICU4X. For terms of use, please see the file
16,348✔
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 super::{reference, runtime, PatternItem};
6
use crate::{fields, options::preferences};
7
#[cfg(feature = "datagen")]
8
use crate::{provider, skeleton};
9
use icu_provider::prelude::*;
10

11
/// Used to represent either H11/H12, or H23/H24. Skeletons only store these
12
/// hour cycles as H12 or H23.
13
#[derive(Debug, PartialEq, Clone, Copy, yoke::Yokeable, zerofrom::ZeroFrom)]
16,391✔
14
#[cfg_attr(
15
    feature = "datagen",
16
    derive(serde::Serialize, databake::Bake),
18✔
17
    databake(path = icu_datetime::pattern),
18
)]
19
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
80✔
20
#[allow(clippy::exhaustive_enums)] // this type is stable
21
pub enum CoarseHourCycle {
20✔
22
    /// Can either be fields::Hour::H11 or fields::Hour::H12
23
    H11H12,
24
    /// Can either be fields::Hour::H23 or fields::Hour::H24
25
    H23H24,
26
}
27

28
/// Default is required for serialization. H23H24 is the more locale-agnostic choice, as it's
29
/// less likely to have a day period in it.
30
impl Default for CoarseHourCycle {
31
    fn default() -> Self {
×
32
        CoarseHourCycle::H23H24
×
33
    }
×
34
}
35

36
impl CoarseHourCycle {
37
    /// Figure out the coarse hour cycle given a pattern, which is useful for generating the provider
38
    /// patterns for `length::Bag`.
39
    pub fn determine(pattern: &reference::Pattern) -> Option<Self> {
16,349✔
40
        for item in pattern.items.iter() {
16,350✔
41
            if let PatternItem::Field(fields::Field {
16,348✔
42
                symbol: fields::FieldSymbol::Hour(pattern_hour),
16,349✔
43
                length: _,
44
            }) = item
45
            {
46
                return Some(match pattern_hour {
32,698✔
47
                    fields::Hour::H11 | fields::Hour::H12 => CoarseHourCycle::H11H12,
7,265✔
48
                    fields::Hour::H23 | fields::Hour::H24 => CoarseHourCycle::H23H24,
9,084✔
49
                });
50
            }
51
        }
52

53
        None
2✔
54
    }
16,351✔
55

56
    /// Invoke the pattern matching machinery to transform the hour cycle of a pattern. This provides
57
    /// a safe mapping from a h11/h12 to h23/h24 for transforms.
58
    #[doc(hidden)]
59
    #[cfg(feature = "datagen")]
60
    pub fn apply_on_pattern<'data>(
16,354✔
61
        &self,
62
        date_time: &provider::calendar::patterns::GenericLengthPatternsV1<'data>,
63
        skeletons: &provider::calendar::DateSkeletonPatternsV1<'data>,
64
        pattern_str: &str,
65
        mut pattern: reference::Pattern,
66
    ) -> Option<reference::Pattern> {
67
        for item in pattern.items_mut() {
16,355✔
68
            if let PatternItem::Field(fields::Field { symbol, length: _ }) = item {
16,347✔
69
                if let fields::FieldSymbol::Hour(pattern_hour) = symbol {
16,347✔
70
                    if match self {
32,696✔
71
                        CoarseHourCycle::H11H12 => match pattern_hour {
9,082✔
72
                            fields::Hour::H11 | fields::Hour::H12 => true,
×
73
                            fields::Hour::H23 | fields::Hour::H24 => false,
9,082✔
74
                        },
75
                        CoarseHourCycle::H23H24 => match pattern_hour {
7,266✔
76
                            fields::Hour::H11 | fields::Hour::H12 => false,
7,266✔
77
                            fields::Hour::H23 | fields::Hour::H24 => true,
×
78
                        },
79
                    } {
80
                        // The preference hour cycle matches the pattern, bail out early and
81
                        // return the current pattern.
UNCOV
82
                        return Some(pattern_str.into());
×
83
                    } else {
84
                        // Mutate the pattern with the new symbol, so that it can be matched against.
85
                        *symbol = fields::FieldSymbol::Hour(match self {
32,696✔
86
                            CoarseHourCycle::H11H12 => fields::Hour::H12,
9,082✔
87
                            CoarseHourCycle::H23H24 => fields::Hour::H23,
7,266✔
88
                        });
89
                        break;
90
                    }
91
                }
92
            }
93
        }
94

95
        let skeleton = skeleton::reference::Skeleton::from(&pattern);
16,355✔
96

97
        match skeleton::create_best_pattern_for_fields(
16,345✔
98
            skeletons,
99
            date_time,
100
            skeleton.as_slice(),
16,352✔
101
            &Default::default(),
16,345✔
102
            // Prefer using the matched pattern directly, rather than mutating it to match the
103
            // requested fields.
104
            true,
105
        ) {
106
            skeleton::BestSkeleton::AllFieldsMatch(patterns)
8,864✔
107
            | skeleton::BestSkeleton::MissingOrExtraFields(patterns) => {
7,488✔
108
                Some(reference::Pattern::from(&patterns.expect_pattern(
16,352✔
109
                    "Only week-of patterns have plural variants",
110
                )))
111
            }
16,351✔
112
            skeleton::BestSkeleton::NoMatch => None,
×
113
        }
114
    }
16,350✔
115

116
    /// Get the other coarse hour cycle (map h11/h12 to h23/h24, and vice versa)
117
    pub fn invert(self) -> Self {
×
118
        match self {
×
119
            CoarseHourCycle::H11H12 => CoarseHourCycle::H23H24,
×
120
            CoarseHourCycle::H23H24 => CoarseHourCycle::H11H12,
×
121
        }
122
    }
×
123
}
124

125
/// The hour cycle can be set by preferences. This function switches between h11 and h12,
126
/// and between h23 and h24. This function is naive as it is assumed that this application of
127
/// the hour cycle will not change between h1x to h2x.
128
pub(crate) fn naively_apply_preferences(
27,559✔
129
    pattern: &mut runtime::Pattern,
130
    preferences: &Option<preferences::Bag>,
131
) {
132
    // If there is a preference overriding the hour cycle, apply it now.
133
    if let Some(preferences::Bag {
27,559✔
134
        hour_cycle: Some(hour_cycle),
74✔
135
    }) = preferences
136
    {
137
        runtime::helpers::maybe_replace_first(pattern, |item| {
342✔
138
            if let PatternItem::Field(fields::Field {
268✔
139
                symbol: fields::FieldSymbol::Hour(current_hour),
74✔
140
                length,
74✔
141
            }) = item
142
            {
143
                if *current_hour != hour_cycle.field() {
74✔
144
                    Some(PatternItem::from((
25✔
145
                        fields::FieldSymbol::Hour(hour_cycle.field()),
25✔
146
                        *length,
25✔
147
                    )))
148
                } else {
149
                    None
49✔
150
                }
151
            } else {
152
                None
194✔
153
            }
154
        });
268✔
155
    }
156
}
27,559✔
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