Coverage Report

Created: 2026-09-06 07:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/time-0.3.41/src/parsing/parsed.rs
Line
Count
Source
1
//! Information parsed from an input and format description.
2
3
use core::num::{NonZeroU16, NonZeroU8};
4
5
use deranged::{
6
    OptionRangedI128, OptionRangedI16, OptionRangedI32, OptionRangedI8, OptionRangedU16,
7
    OptionRangedU32, OptionRangedU8, RangedI128, RangedI16, RangedI32, RangedI8, RangedU16,
8
    RangedU32, RangedU8,
9
};
10
use num_conv::prelude::*;
11
12
use crate::convert::{Day, Hour, Minute, Nanosecond, Second};
13
use crate::date::{MAX_YEAR, MIN_YEAR};
14
use crate::error::TryFromParsed::InsufficientInformation;
15
#[cfg(feature = "alloc")]
16
use crate::format_description::OwnedFormatItem;
17
use crate::format_description::{modifier, BorrowedFormatItem, Component};
18
use crate::internal_macros::{bug, const_try_opt};
19
use crate::parsing::component::{
20
    parse_day, parse_end, parse_hour, parse_ignore, parse_minute, parse_month, parse_offset_hour,
21
    parse_offset_minute, parse_offset_second, parse_ordinal, parse_period, parse_second,
22
    parse_subsecond, parse_unix_timestamp, parse_week_number, parse_weekday, parse_year, Period,
23
};
24
use crate::parsing::ParsedItem;
25
use crate::{
26
    error, Date, Month, OffsetDateTime, PrimitiveDateTime, Time, UtcDateTime, UtcOffset, Weekday,
27
};
28
29
/// Sealed to prevent downstream implementations.
30
mod sealed {
31
    use super::*;
32
33
    /// A trait to allow `parse_item` to be generic.
34
    pub trait AnyFormatItem {
35
        /// Parse a single item, returning the remaining input on success.
36
        fn parse_item<'a>(
37
            &self,
38
            parsed: &mut Parsed,
39
            input: &'a [u8],
40
        ) -> Result<&'a [u8], error::ParseFromDescription>;
41
    }
42
}
43
44
impl sealed::AnyFormatItem for BorrowedFormatItem<'_> {
45
0
    fn parse_item<'a>(
46
0
        &self,
47
0
        parsed: &mut Parsed,
48
0
        input: &'a [u8],
49
0
    ) -> Result<&'a [u8], error::ParseFromDescription> {
50
0
        match self {
51
0
            Self::Literal(literal) => Parsed::parse_literal(input, literal),
52
0
            Self::Component(component) => parsed.parse_component(input, *component),
53
0
            Self::Compound(compound) => parsed.parse_items(input, compound),
54
0
            Self::Optional(item) => parsed.parse_item(input, *item).or(Ok(input)),
55
0
            Self::First(items) => {
56
0
                let mut first_err = None;
57
58
0
                for item in items.iter() {
59
0
                    match parsed.parse_item(input, item) {
60
0
                        Ok(remaining_input) => return Ok(remaining_input),
61
0
                        Err(err) if first_err.is_none() => first_err = Some(err),
62
0
                        Err(_) => {}
63
                    }
64
                }
65
66
0
                match first_err {
67
0
                    Some(err) => Err(err),
68
                    // This location will be reached if the slice is empty, skipping the `for` loop.
69
                    // As this case is expected to be uncommon, there's no need to check up front.
70
0
                    None => Ok(input),
71
                }
72
            }
73
        }
74
0
    }
Unexecuted instantiation: <time::format_description::borrowed_format_item::BorrowedFormatItem as time::parsing::parsed::sealed::AnyFormatItem>::parse_item
Unexecuted instantiation: <time::format_description::borrowed_format_item::BorrowedFormatItem as time::parsing::parsed::sealed::AnyFormatItem>::parse_item
75
}
76
77
#[cfg(feature = "alloc")]
78
impl sealed::AnyFormatItem for OwnedFormatItem {
79
0
    fn parse_item<'a>(
80
0
        &self,
81
0
        parsed: &mut Parsed,
82
0
        input: &'a [u8],
83
0
    ) -> Result<&'a [u8], error::ParseFromDescription> {
84
0
        match self {
85
0
            Self::Literal(literal) => Parsed::parse_literal(input, literal),
86
0
            Self::Component(component) => parsed.parse_component(input, *component),
87
0
            Self::Compound(compound) => parsed.parse_items(input, compound),
88
0
            Self::Optional(item) => parsed.parse_item(input, item.as_ref()).or(Ok(input)),
89
0
            Self::First(items) => {
90
0
                let mut first_err = None;
91
92
0
                for item in items.iter() {
93
0
                    match parsed.parse_item(input, item) {
94
0
                        Ok(remaining_input) => return Ok(remaining_input),
95
0
                        Err(err) if first_err.is_none() => first_err = Some(err),
96
0
                        Err(_) => {}
97
                    }
98
                }
99
100
0
                match first_err {
101
0
                    Some(err) => Err(err),
102
                    // This location will be reached if the slice is empty, skipping the `for` loop.
103
                    // As this case is expected to be uncommon, there's no need to check up front.
104
0
                    None => Ok(input),
105
                }
106
            }
107
        }
108
0
    }
Unexecuted instantiation: <time::format_description::owned_format_item::OwnedFormatItem as time::parsing::parsed::sealed::AnyFormatItem>::parse_item
Unexecuted instantiation: <time::format_description::owned_format_item::OwnedFormatItem as time::parsing::parsed::sealed::AnyFormatItem>::parse_item
109
}
110
111
/// All information parsed.
112
///
113
/// This information is directly used to construct the final values.
114
///
115
/// Most users will not need think about this struct in any way. It is public to allow for manual
116
/// control over values, in the instance that the default parser is insufficient.
117
#[derive(Debug, Clone, Copy)]
118
pub struct Parsed {
119
    /// Calendar year.
120
    year: OptionRangedI32<{ MIN_YEAR }, { MAX_YEAR }>,
121
    /// All digits except the last two of the calendar year.
122
    year_century: OptionRangedI16<{ (MIN_YEAR / 100) as i16 }, { (MAX_YEAR / 100) as i16 }>,
123
    /// The last two digits of the calendar year.
124
    year_last_two: OptionRangedU8<0, 99>,
125
    /// Year of the [ISO week date](https://en.wikipedia.org/wiki/ISO_week_date).
126
    iso_year: OptionRangedI32<{ MIN_YEAR }, { MAX_YEAR }>,
127
    /// All digits except the last two of the ISO week year.
128
    iso_year_century: OptionRangedI16<{ (MIN_YEAR / 100) as i16 }, { (MAX_YEAR / 100) as i16 }>,
129
    /// The last two digits of the ISO week year.
130
    iso_year_last_two: OptionRangedU8<0, 99>,
131
    /// Month of the year.
132
    month: Option<Month>,
133
    /// Week of the year, where week one begins on the first Sunday of the calendar year.
134
    sunday_week_number: OptionRangedU8<0, 53>,
135
    /// Week of the year, where week one begins on the first Monday of the calendar year.
136
    monday_week_number: OptionRangedU8<0, 53>,
137
    /// Week of the year, where week one is the Monday-to-Sunday period containing January 4.
138
    iso_week_number: OptionRangedU8<1, 53>,
139
    /// Day of the week.
140
    weekday: Option<Weekday>,
141
    /// Day of the year.
142
    ordinal: OptionRangedU16<1, 366>,
143
    /// Day of the month.
144
    day: OptionRangedU8<1, 31>,
145
    /// Hour within the day.
146
    hour_24: OptionRangedU8<0, { Hour::per(Day) - 1 }>,
147
    /// Hour within the 12-hour period (midnight to noon or vice versa). This is typically used in
148
    /// conjunction with AM/PM, which is indicated by the `hour_12_is_pm` field.
149
    hour_12: OptionRangedU8<1, 12>,
150
    /// Whether the `hour_12` field indicates a time that "PM".
151
    hour_12_is_pm: Option<bool>,
152
    /// Minute within the hour.
153
    minute: OptionRangedU8<0, { Minute::per(Hour) - 1 }>,
154
    /// Second within the minute.
155
    // do not subtract one, as leap seconds may be allowed
156
    second: OptionRangedU8<0, { Second::per(Minute) }>,
157
    /// Nanosecond within the second.
158
    subsecond: OptionRangedU32<0, { Nanosecond::per(Second) - 1 }>,
159
    /// Whole hours of the UTC offset.
160
    offset_hour: OptionRangedI8<-23, 23>,
161
    /// Minutes within the hour of the UTC offset.
162
    offset_minute:
163
        OptionRangedI8<{ -((Minute::per(Hour) - 1) as i8) }, { (Minute::per(Hour) - 1) as i8 }>,
164
    /// Seconds within the minute of the UTC offset.
165
    offset_second:
166
        OptionRangedI8<{ -((Second::per(Minute) - 1) as i8) }, { (Second::per(Minute) - 1) as i8 }>,
167
    /// The Unix timestamp in nanoseconds.
168
    unix_timestamp_nanos: OptionRangedI128<
169
        {
170
            OffsetDateTime::new_in_offset(Date::MIN, Time::MIDNIGHT, UtcOffset::UTC)
171
                .unix_timestamp_nanos()
172
        },
173
        {
174
            OffsetDateTime::new_in_offset(Date::MAX, Time::MAX, UtcOffset::UTC)
175
                .unix_timestamp_nanos()
176
        },
177
    >,
178
    /// Indicates whether the [`UtcOffset`] is negative. This information is obtained when parsing
179
    /// the offset hour, but may not otherwise be stored due to "-0" being equivalent to "0".
180
    offset_is_negative: bool,
181
    /// Indicates whether the `year_century` component is negative. This information is obtained
182
    /// when parsing, but may not otherwise be stored due to "-0" being equivalent to "0".
183
    year_century_is_negative: bool,
184
    /// Indicates whether the `iso_year_century` component is negative. This information is
185
    /// obtained when parsing, but may not otherwise be stored due to "-0" being equivalent to "0".
186
    iso_year_century_is_negative: bool,
187
    /// Indicates whether a leap second is permitted to be parsed. This is required by some
188
    /// well-known formats.
189
    pub(super) leap_second_allowed: bool,
190
}
191
192
impl Default for Parsed {
193
0
    fn default() -> Self {
194
0
        Self::new()
195
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed as core::default::Default>::default
Unexecuted instantiation: <time::parsing::parsed::Parsed as core::default::Default>::default
196
}
197
198
impl Parsed {
199
    /// Create a new instance of `Parsed` with no information known.
200
0
    pub const fn new() -> Self {
201
0
        Self {
202
0
            year: OptionRangedI32::None,
203
0
            year_century: OptionRangedI16::None,
204
0
            year_last_two: OptionRangedU8::None,
205
0
            iso_year: OptionRangedI32::None,
206
0
            iso_year_century: OptionRangedI16::None,
207
0
            iso_year_last_two: OptionRangedU8::None,
208
0
            month: None,
209
0
            sunday_week_number: OptionRangedU8::None,
210
0
            monday_week_number: OptionRangedU8::None,
211
0
            iso_week_number: OptionRangedU8::None,
212
0
            weekday: None,
213
0
            ordinal: OptionRangedU16::None,
214
0
            day: OptionRangedU8::None,
215
0
            hour_24: OptionRangedU8::None,
216
0
            hour_12: OptionRangedU8::None,
217
0
            hour_12_is_pm: None,
218
0
            minute: OptionRangedU8::None,
219
0
            second: OptionRangedU8::None,
220
0
            subsecond: OptionRangedU32::None,
221
0
            offset_hour: OptionRangedI8::None,
222
0
            offset_minute: OptionRangedI8::None,
223
0
            offset_second: OptionRangedI8::None,
224
0
            unix_timestamp_nanos: OptionRangedI128::None,
225
0
            offset_is_negative: false,
226
0
            year_century_is_negative: false,
227
0
            iso_year_century_is_negative: false,
228
0
            leap_second_allowed: false,
229
0
        }
230
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::new
Unexecuted instantiation: <time::parsing::parsed::Parsed>::new
231
232
    /// Parse a single [`BorrowedFormatItem`] or [`OwnedFormatItem`], mutating the struct. The
233
    /// remaining input is returned as the `Ok` value.
234
    ///
235
    /// If a [`BorrowedFormatItem::Optional`] or [`OwnedFormatItem::Optional`] is passed, parsing
236
    /// will not fail; the input will be returned as-is if the expected format is not present.
237
0
    pub fn parse_item<'a>(
238
0
        &mut self,
239
0
        input: &'a [u8],
240
0
        item: &impl sealed::AnyFormatItem,
241
0
    ) -> Result<&'a [u8], error::ParseFromDescription> {
242
0
        item.parse_item(self, input)
243
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_item::<time::format_description::owned_format_item::OwnedFormatItem>
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_item::<time::format_description::borrowed_format_item::BorrowedFormatItem>
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_item::<time::format_description::owned_format_item::OwnedFormatItem>
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_item::<time::format_description::borrowed_format_item::BorrowedFormatItem>
244
245
    /// Parse a sequence of [`BorrowedFormatItem`]s or [`OwnedFormatItem`]s, mutating the struct.
246
    /// The remaining input is returned as the `Ok` value.
247
    ///
248
    /// This method will fail if any of the contained [`BorrowedFormatItem`]s or
249
    /// [`OwnedFormatItem`]s fail to parse. `self` will not be mutated in this instance.
250
0
    pub fn parse_items<'a>(
251
0
        &mut self,
252
0
        mut input: &'a [u8],
253
0
        items: &[impl sealed::AnyFormatItem],
254
0
    ) -> Result<&'a [u8], error::ParseFromDescription> {
255
        // Make a copy that we can mutate. It will only be set to the user's copy if everything
256
        // succeeds.
257
0
        let mut this = *self;
258
0
        for item in items {
259
0
            input = this.parse_item(input, item)?;
260
        }
261
0
        *self = this;
262
0
        Ok(input)
263
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_items::<time::format_description::owned_format_item::OwnedFormatItem>
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_items::<time::format_description::borrowed_format_item::BorrowedFormatItem>
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_items::<time::format_description::owned_format_item::OwnedFormatItem>
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_items::<time::format_description::borrowed_format_item::BorrowedFormatItem>
264
265
    /// Parse a literal byte sequence. The remaining input is returned as the `Ok` value.
266
0
    pub fn parse_literal<'a>(
267
0
        input: &'a [u8],
268
0
        literal: &[u8],
269
0
    ) -> Result<&'a [u8], error::ParseFromDescription> {
270
0
        input
271
0
            .strip_prefix(literal)
272
0
            .ok_or(error::ParseFromDescription::InvalidLiteral)
273
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_literal
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_literal
274
275
    /// Parse a single component, mutating the struct. The remaining input is returned as the `Ok`
276
    /// value.
277
0
    pub fn parse_component<'a>(
278
0
        &mut self,
279
0
        input: &'a [u8],
280
0
        component: Component,
281
0
    ) -> Result<&'a [u8], error::ParseFromDescription> {
282
        use error::ParseFromDescription::InvalidComponent;
283
284
0
        match component {
285
0
            Component::Day(modifiers) => parse_day(input, modifiers)
286
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_day(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#0}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#0}::{closure#0}
287
0
                .ok_or(InvalidComponent("day")),
288
0
            Component::Month(modifiers) => parse_month(input, modifiers)
289
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_month(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#1}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#1}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#1}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#1}::{closure#0}
290
0
                .ok_or(InvalidComponent("month")),
291
0
            Component::Ordinal(modifiers) => parse_ordinal(input, modifiers)
292
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_ordinal(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#2}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#2}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#2}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#2}::{closure#0}
293
0
                .ok_or(InvalidComponent("ordinal")),
294
0
            Component::Weekday(modifiers) => parse_weekday(input, modifiers)
295
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_weekday(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#3}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#3}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#3}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#3}::{closure#0}
296
0
                .ok_or(InvalidComponent("weekday")),
297
0
            Component::WeekNumber(modifiers) => {
298
0
                let ParsedItem(remaining, value) =
299
0
                    parse_week_number(input, modifiers).ok_or(InvalidComponent("week number"))?;
300
0
                match modifiers.repr {
301
                    modifier::WeekNumberRepr::Iso => {
302
0
                        NonZeroU8::new(value).and_then(|value| self.set_iso_week_number(value))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#4}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#4}
303
                    }
304
0
                    modifier::WeekNumberRepr::Sunday => self.set_sunday_week_number(value),
305
0
                    modifier::WeekNumberRepr::Monday => self.set_monday_week_number(value),
306
                }
307
0
                .ok_or(InvalidComponent("week number"))?;
308
0
                Ok(remaining)
309
            }
310
0
            Component::Year(modifiers) => {
311
0
                let ParsedItem(remaining, (value, is_negative)) =
312
0
                    parse_year(input, modifiers).ok_or(InvalidComponent("year"))?;
313
0
                match (modifiers.iso_week_based, modifiers.repr) {
314
0
                    (false, modifier::YearRepr::Full) => self.set_year(value),
315
                    (false, modifier::YearRepr::Century) => {
316
0
                        self.set_year_century(value.truncate(), is_negative)
317
                    }
318
                    (false, modifier::YearRepr::LastTwo) => {
319
0
                        self.set_year_last_two(value.cast_unsigned().truncate())
320
                    }
321
0
                    (true, modifier::YearRepr::Full) => self.set_iso_year(value),
322
                    (true, modifier::YearRepr::Century) => {
323
0
                        self.set_iso_year_century(value.truncate(), is_negative)
324
                    }
325
                    (true, modifier::YearRepr::LastTwo) => {
326
0
                        self.set_iso_year_last_two(value.cast_unsigned().truncate())
327
                    }
328
                }
329
0
                .ok_or(InvalidComponent("year"))?;
330
0
                Ok(remaining)
331
            }
332
0
            Component::Hour(modifiers) => {
333
0
                let ParsedItem(remaining, value) =
334
0
                    parse_hour(input, modifiers).ok_or(InvalidComponent("hour"))?;
335
0
                if modifiers.is_12_hour_clock {
336
0
                    NonZeroU8::new(value).and_then(|value| self.set_hour_12(value))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#5}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#5}
337
                } else {
338
0
                    self.set_hour_24(value)
339
                }
340
0
                .ok_or(InvalidComponent("hour"))?;
341
0
                Ok(remaining)
342
            }
343
0
            Component::Minute(modifiers) => parse_minute(input, modifiers)
344
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_minute(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#6}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#6}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#6}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#6}::{closure#0}
345
0
                .ok_or(InvalidComponent("minute")),
346
0
            Component::Period(modifiers) => parse_period(input, modifiers)
347
0
                .and_then(|parsed| {
348
0
                    parsed.consume_value(|value| self.set_hour_12_is_pm(value == Period::Pm))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#7}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#7}::{closure#0}
349
0
                })
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#7}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#7}
350
0
                .ok_or(InvalidComponent("period")),
351
0
            Component::Second(modifiers) => parse_second(input, modifiers)
352
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_second(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#8}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#8}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#8}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#8}::{closure#0}
353
0
                .ok_or(InvalidComponent("second")),
354
0
            Component::Subsecond(modifiers) => parse_subsecond(input, modifiers)
355
0
                .and_then(|parsed| parsed.consume_value(|value| self.set_subsecond(value)))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#9}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#9}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#9}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#9}::{closure#0}
356
0
                .ok_or(InvalidComponent("subsecond")),
357
0
            Component::OffsetHour(modifiers) => parse_offset_hour(input, modifiers)
358
0
                .and_then(|parsed| {
359
0
                    parsed.consume_value(|(value, is_negative)| {
360
0
                        self.set_offset_hour(value)?;
361
0
                        self.offset_is_negative = is_negative;
362
0
                        Some(())
363
0
                    })
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#10}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#10}::{closure#0}
364
0
                })
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#10}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#10}
365
0
                .ok_or(InvalidComponent("offset hour")),
366
0
            Component::OffsetMinute(modifiers) => parse_offset_minute(input, modifiers)
367
0
                .and_then(|parsed| {
368
0
                    parsed.consume_value(|value| self.set_offset_minute_signed(value))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#11}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#11}::{closure#0}
369
0
                })
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#11}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#11}
370
0
                .ok_or(InvalidComponent("offset minute")),
371
0
            Component::OffsetSecond(modifiers) => parse_offset_second(input, modifiers)
372
0
                .and_then(|parsed| {
373
0
                    parsed.consume_value(|value| self.set_offset_second_signed(value))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#12}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#12}::{closure#0}
374
0
                })
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#12}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#12}
375
0
                .ok_or(InvalidComponent("offset second")),
376
0
            Component::Ignore(modifiers) => parse_ignore(input, modifiers)
377
0
                .map(ParsedItem::<()>::into_inner)
378
0
                .ok_or(InvalidComponent("ignore")),
379
0
            Component::UnixTimestamp(modifiers) => parse_unix_timestamp(input, modifiers)
380
0
                .and_then(|parsed| {
381
0
                    parsed.consume_value(|value| self.set_unix_timestamp_nanos(value))
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#13}::{closure#0}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#13}::{closure#0}
382
0
                })
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#13}
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component::{closure#13}
383
0
                .ok_or(InvalidComponent("unix_timestamp")),
384
0
            Component::End(modifiers) => parse_end(input, modifiers)
385
0
                .map(ParsedItem::<()>::into_inner)
386
0
                .ok_or(error::ParseFromDescription::UnexpectedTrailingCharacters),
387
        }
388
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component
Unexecuted instantiation: <time::parsing::parsed::Parsed>::parse_component
389
}
390
391
/// Getter methods
392
impl Parsed {
393
    /// Obtain the `year` component.
394
0
    pub const fn year(&self) -> Option<i32> {
395
0
        self.year.get_primitive()
396
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year
397
398
    /// Obtain the `year_century` component.
399
    ///
400
    /// If the year is zero, the sign of the century is not stored. To differentiate between
401
    /// positive and negative zero, use `year_century_is_negative`.
402
0
    pub const fn year_century(&self) -> Option<i16> {
403
0
        self.year_century.get_primitive()
404
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year_century
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year_century
405
406
    /// Obtain the `year_century_is_negative` component.
407
    ///
408
    /// This indicates whether the value returned from `year_century` is negative. If the year is
409
    /// zero, it is necessary to call this method for disambiguation.
410
0
    pub const fn year_century_is_negative(&self) -> Option<bool> {
411
0
        match self.year_century() {
412
0
            Some(_) => Some(self.year_century_is_negative),
413
0
            None => None,
414
        }
415
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year_century_is_negative
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year_century_is_negative
416
417
    /// Obtain the `year_last_two` component.
418
0
    pub const fn year_last_two(&self) -> Option<u8> {
419
0
        self.year_last_two.get_primitive()
420
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::year_last_two
421
422
    /// Obtain the `iso_year` component.
423
0
    pub const fn iso_year(&self) -> Option<i32> {
424
0
        self.iso_year.get_primitive()
425
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year
426
427
    /// Obtain the `iso_year_century` component.
428
    ///
429
    /// If the year is zero, the sign of the century is not stored. To differentiate between
430
    /// positive and negative zero, use `iso_year_century_is_negative`.
431
0
    pub const fn iso_year_century(&self) -> Option<i16> {
432
0
        self.iso_year_century.get_primitive()
433
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year_century
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year_century
434
435
    /// Obtain the `iso_year_century_is_negative` component.
436
    ///
437
    /// This indicates whether the value returned from `iso_year_century` is negative. If the year
438
    /// is zero, it is necessary to call this method for disambiguation.
439
0
    pub const fn iso_year_century_is_negative(&self) -> Option<bool> {
440
0
        match self.iso_year_century() {
441
0
            Some(_) => Some(self.iso_year_century_is_negative),
442
0
            None => None,
443
        }
444
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year_century_is_negative
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year_century_is_negative
445
446
    /// Obtain the `iso_year_last_two` component.
447
0
    pub const fn iso_year_last_two(&self) -> Option<u8> {
448
0
        self.iso_year_last_two.get_primitive()
449
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_year_last_two
450
451
    /// Obtain the `month` component.
452
0
    pub const fn month(&self) -> Option<Month> {
453
0
        self.month
454
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::month
Unexecuted instantiation: <time::parsing::parsed::Parsed>::month
455
456
    /// Obtain the `sunday_week_number` component.
457
0
    pub const fn sunday_week_number(&self) -> Option<u8> {
458
0
        self.sunday_week_number.get_primitive()
459
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::sunday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::sunday_week_number
460
461
    /// Obtain the `monday_week_number` component.
462
0
    pub const fn monday_week_number(&self) -> Option<u8> {
463
0
        self.monday_week_number.get_primitive()
464
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::monday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::monday_week_number
465
466
    /// Obtain the `iso_week_number` component.
467
0
    pub const fn iso_week_number(&self) -> Option<NonZeroU8> {
468
0
        NonZeroU8::new(const_try_opt!(self.iso_week_number.get_primitive()))
469
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::iso_week_number
470
471
    /// Obtain the `weekday` component.
472
0
    pub const fn weekday(&self) -> Option<Weekday> {
473
0
        self.weekday
474
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::weekday
Unexecuted instantiation: <time::parsing::parsed::Parsed>::weekday
475
476
    /// Obtain the `ordinal` component.
477
0
    pub const fn ordinal(&self) -> Option<NonZeroU16> {
478
0
        NonZeroU16::new(const_try_opt!(self.ordinal.get_primitive()))
479
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::ordinal
Unexecuted instantiation: <time::parsing::parsed::Parsed>::ordinal
480
481
    /// Obtain the `day` component.
482
0
    pub const fn day(&self) -> Option<NonZeroU8> {
483
0
        NonZeroU8::new(const_try_opt!(self.day.get_primitive()))
484
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::day
Unexecuted instantiation: <time::parsing::parsed::Parsed>::day
485
486
    /// Obtain the `hour_24` component.
487
0
    pub const fn hour_24(&self) -> Option<u8> {
488
0
        self.hour_24.get_primitive()
489
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::hour_24
Unexecuted instantiation: <time::parsing::parsed::Parsed>::hour_24
490
491
    /// Obtain the `hour_12` component.
492
0
    pub const fn hour_12(&self) -> Option<NonZeroU8> {
493
0
        NonZeroU8::new(const_try_opt!(self.hour_12.get_primitive()))
494
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::hour_12
Unexecuted instantiation: <time::parsing::parsed::Parsed>::hour_12
495
496
    /// Obtain the `hour_12_is_pm` component.
497
0
    pub const fn hour_12_is_pm(&self) -> Option<bool> {
498
0
        self.hour_12_is_pm
499
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::hour_12_is_pm
Unexecuted instantiation: <time::parsing::parsed::Parsed>::hour_12_is_pm
500
501
    /// Obtain the `minute` component.
502
0
    pub const fn minute(&self) -> Option<u8> {
503
0
        self.minute.get_primitive()
504
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::minute
505
506
    /// Obtain the `second` component.
507
0
    pub const fn second(&self) -> Option<u8> {
508
0
        self.second.get_primitive()
509
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::second
510
511
    /// Obtain the `subsecond` component.
512
0
    pub const fn subsecond(&self) -> Option<u32> {
513
0
        self.subsecond.get_primitive()
514
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::subsecond
Unexecuted instantiation: <time::parsing::parsed::Parsed>::subsecond
515
516
    /// Obtain the `offset_hour` component.
517
0
    pub const fn offset_hour(&self) -> Option<i8> {
518
0
        self.offset_hour.get_primitive()
519
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_hour
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_hour
520
521
    /// Obtain the absolute value of the `offset_minute` component.
522
    #[doc(hidden)]
523
    #[deprecated(since = "0.3.8", note = "use `parsed.offset_minute_signed()` instead")]
524
0
    pub const fn offset_minute(&self) -> Option<u8> {
525
0
        Some(const_try_opt!(self.offset_minute_signed()).unsigned_abs())
526
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_minute
527
528
    /// Obtain the `offset_minute` component.
529
0
    pub const fn offset_minute_signed(&self) -> Option<i8> {
530
0
        match (self.offset_minute.get_primitive(), self.offset_is_negative) {
531
0
            (Some(offset_minute), true) => Some(-offset_minute),
532
0
            (Some(offset_minute), _) => Some(offset_minute),
533
0
            (None, _) => None,
534
        }
535
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_minute_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_minute_signed
536
537
    /// Obtain the absolute value of the `offset_second` component.
538
    #[doc(hidden)]
539
    #[deprecated(since = "0.3.8", note = "use `parsed.offset_second_signed()` instead")]
540
0
    pub const fn offset_second(&self) -> Option<u8> {
541
0
        Some(const_try_opt!(self.offset_second_signed()).unsigned_abs())
542
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_second
543
544
    /// Obtain the `offset_second` component.
545
0
    pub const fn offset_second_signed(&self) -> Option<i8> {
546
0
        match (self.offset_second.get_primitive(), self.offset_is_negative) {
547
0
            (Some(offset_second), true) => Some(-offset_second),
548
0
            (Some(offset_second), _) => Some(offset_second),
549
0
            (None, _) => None,
550
        }
551
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_second_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::offset_second_signed
552
553
    /// Obtain the `unix_timestamp_nanos` component.
554
0
    pub const fn unix_timestamp_nanos(&self) -> Option<i128> {
555
0
        self.unix_timestamp_nanos.get_primitive()
556
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::unix_timestamp_nanos
Unexecuted instantiation: <time::parsing::parsed::Parsed>::unix_timestamp_nanos
557
}
558
559
/// Generate setters based on the builders.
560
macro_rules! setters {
561
    ($($name:ident $setter:ident $builder:ident $type:ty;)*) => {$(
562
        #[doc = concat!("Set the `", stringify!($name), "` component.")]
563
0
        pub fn $setter(&mut self, value: $type) -> Option<()> {
564
0
            *self = self.$builder(value)?;
565
0
            Some(())
566
0
        }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_hour_12
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_hour_24
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_ordinal
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_weekday
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_subsecond
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_hour
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_hour_12_is_pm
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_monday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_sunday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_minute_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_second_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_unix_timestamp_nanos
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_day
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_month
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_hour_12
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_hour_24
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_ordinal
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_weekday
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_subsecond
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_hour
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_hour_12_is_pm
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_monday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_sunday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_minute_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_second_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_unix_timestamp_nanos
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_day
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_month
567
    )*};
568
}
569
570
/// Setter methods
571
///
572
/// All setters return `Option<()>`, which is `Some` if the value was set, and `None` if not. The
573
/// setters _may_ fail if the value is invalid, though behavior is not guaranteed.
574
impl Parsed {
575
    setters! {
576
        year set_year with_year i32;
577
    }
578
579
    /// Set the `year_century` component.
580
    ///
581
    /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise
582
    /// the sign is inferred from the value.
583
0
    pub fn set_year_century(&mut self, value: i16, is_negative: bool) -> Option<()> {
584
0
        self.year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value)));
585
0
        if value != 0 {
586
0
            self.year_century_is_negative = value.is_negative();
587
0
        } else {
588
0
            self.year_century_is_negative = is_negative;
589
0
        }
590
0
        Some(())
591
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_year_century
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_year_century
592
593
    setters! {
594
        year_last_two set_year_last_two with_year_last_two u8;
595
        iso_year set_iso_year with_iso_year i32;
596
        iso_year_last_two set_iso_year_last_two with_iso_year_last_two u8;
597
    }
598
599
    /// Set the `iso_year_century` component.
600
    ///
601
    /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise
602
    /// the sign is inferred from the value.
603
0
    pub fn set_iso_year_century(&mut self, value: i16, is_negative: bool) -> Option<()> {
604
0
        self.iso_year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value)));
605
0
        if value != 0 {
606
0
            self.iso_year_century_is_negative = value.is_negative();
607
0
        } else {
608
0
            self.iso_year_century_is_negative = is_negative;
609
0
        }
610
0
        Some(())
611
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_year_century
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_iso_year_century
612
613
    setters! {
614
        month set_month with_month Month;
615
        sunday_week_number set_sunday_week_number with_sunday_week_number u8;
616
        monday_week_number set_monday_week_number with_monday_week_number u8;
617
        iso_week_number set_iso_week_number with_iso_week_number NonZeroU8;
618
        weekday set_weekday with_weekday Weekday;
619
        ordinal set_ordinal with_ordinal NonZeroU16;
620
        day set_day with_day NonZeroU8;
621
        hour_24 set_hour_24 with_hour_24 u8;
622
        hour_12 set_hour_12 with_hour_12 NonZeroU8;
623
        hour_12_is_pm set_hour_12_is_pm with_hour_12_is_pm bool;
624
        minute set_minute with_minute u8;
625
        second set_second with_second u8;
626
        subsecond set_subsecond with_subsecond u32;
627
        offset_hour set_offset_hour with_offset_hour i8;
628
        offset_minute set_offset_minute_signed with_offset_minute_signed i8;
629
        offset_second set_offset_second_signed with_offset_second_signed i8;
630
        unix_timestamp_nanos set_unix_timestamp_nanos with_unix_timestamp_nanos i128;
631
    }
632
633
    /// Set the `offset_minute` component.
634
    #[doc(hidden)]
635
    #[deprecated(
636
        since = "0.3.8",
637
        note = "use `parsed.set_offset_minute_signed()` instead"
638
    )]
639
0
    pub fn set_offset_minute(&mut self, value: u8) -> Option<()> {
640
0
        if value > i8::MAX.cast_unsigned() {
641
0
            None
642
        } else {
643
0
            self.set_offset_minute_signed(value.cast_signed())
644
        }
645
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_minute
646
647
    /// Set the `offset_minute` component.
648
    #[doc(hidden)]
649
    #[deprecated(
650
        since = "0.3.8",
651
        note = "use `parsed.set_offset_second_signed()` instead"
652
    )]
653
0
    pub fn set_offset_second(&mut self, value: u8) -> Option<()> {
654
0
        if value > i8::MAX.cast_unsigned() {
655
0
            None
656
        } else {
657
0
            self.set_offset_second_signed(value.cast_signed())
658
        }
659
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::set_offset_second
660
}
661
662
/// Builder methods
663
///
664
/// All builder methods return `Option<Self>`, which is `Some` if the value was set, and `None` if
665
/// not. The builder methods _may_ fail if the value is invalid, though behavior is not guaranteed.
666
impl Parsed {
667
    /// Set the `year` component and return `self`.
668
0
    pub const fn with_year(mut self, value: i32) -> Option<Self> {
669
0
        self.year = OptionRangedI32::Some(const_try_opt!(RangedI32::new(value)));
670
0
        Some(self)
671
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_year
672
673
    /// Set the `year_century` component and return `self`.
674
    ///
675
    /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise
676
    /// the sign is inferred from the value.
677
0
    pub const fn with_year_century(mut self, value: i16, is_negative: bool) -> Option<Self> {
678
0
        self.year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value)));
679
0
        if value != 0 {
680
0
            self.year_century_is_negative = value.is_negative();
681
0
        } else {
682
0
            self.year_century_is_negative = is_negative;
683
0
        }
684
0
        Some(self)
685
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_year_century
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_year_century
686
687
    /// Set the `year_last_two` component and return `self`.
688
0
    pub const fn with_year_last_two(mut self, value: u8) -> Option<Self> {
689
0
        self.year_last_two = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
690
0
        Some(self)
691
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_year_last_two
692
693
    /// Set the `iso_year` component and return `self`.
694
0
    pub const fn with_iso_year(mut self, value: i32) -> Option<Self> {
695
0
        self.iso_year = OptionRangedI32::Some(const_try_opt!(RangedI32::new(value)));
696
0
        Some(self)
697
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_year
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_year
698
699
    /// Set the `iso_year_century` component and return `self`.
700
    ///
701
    /// If the value is zero, the sign of the century is taken from the second parameter. Otherwise
702
    /// the sign is inferred from the value.
703
0
    pub const fn with_iso_year_century(mut self, value: i16, is_negative: bool) -> Option<Self> {
704
0
        self.iso_year_century = OptionRangedI16::Some(const_try_opt!(RangedI16::new(value)));
705
0
        if value != 0 {
706
0
            self.iso_year_century_is_negative = value.is_negative();
707
0
        } else {
708
0
            self.iso_year_century_is_negative = is_negative;
709
0
        }
710
0
        Some(self)
711
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_year_century
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_year_century
712
713
    /// Set the `iso_year_last_two` component and return `self`.
714
0
    pub const fn with_iso_year_last_two(mut self, value: u8) -> Option<Self> {
715
0
        self.iso_year_last_two = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
716
0
        Some(self)
717
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_year_last_two
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_year_last_two
718
719
    /// Set the `month` component and return `self`.
720
0
    pub const fn with_month(mut self, value: Month) -> Option<Self> {
721
0
        self.month = Some(value);
722
0
        Some(self)
723
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_month
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_month
724
725
    /// Set the `sunday_week_number` component and return `self`.
726
0
    pub const fn with_sunday_week_number(mut self, value: u8) -> Option<Self> {
727
0
        self.sunday_week_number = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
728
0
        Some(self)
729
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_sunday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_sunday_week_number
730
731
    /// Set the `monday_week_number` component and return `self`.
732
0
    pub const fn with_monday_week_number(mut self, value: u8) -> Option<Self> {
733
0
        self.monday_week_number = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
734
0
        Some(self)
735
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_monday_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_monday_week_number
736
737
    /// Set the `iso_week_number` component and return `self`.
738
0
    pub const fn with_iso_week_number(mut self, value: NonZeroU8) -> Option<Self> {
739
0
        self.iso_week_number = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value.get())));
740
0
        Some(self)
741
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_week_number
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_iso_week_number
742
743
    /// Set the `weekday` component and return `self`.
744
0
    pub const fn with_weekday(mut self, value: Weekday) -> Option<Self> {
745
0
        self.weekday = Some(value);
746
0
        Some(self)
747
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_weekday
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_weekday
748
749
    /// Set the `ordinal` component and return `self`.
750
0
    pub const fn with_ordinal(mut self, value: NonZeroU16) -> Option<Self> {
751
0
        self.ordinal = OptionRangedU16::Some(const_try_opt!(RangedU16::new(value.get())));
752
0
        Some(self)
753
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_ordinal
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_ordinal
754
755
    /// Set the `day` component and return `self`.
756
0
    pub const fn with_day(mut self, value: NonZeroU8) -> Option<Self> {
757
0
        self.day = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value.get())));
758
0
        Some(self)
759
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_day
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_day
760
761
    /// Set the `hour_24` component and return `self`.
762
0
    pub const fn with_hour_24(mut self, value: u8) -> Option<Self> {
763
0
        self.hour_24 = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
764
0
        Some(self)
765
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_hour_24
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_hour_24
766
767
    /// Set the `hour_12` component and return `self`.
768
0
    pub const fn with_hour_12(mut self, value: NonZeroU8) -> Option<Self> {
769
0
        self.hour_12 = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value.get())));
770
0
        Some(self)
771
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_hour_12
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_hour_12
772
773
    /// Set the `hour_12_is_pm` component and return `self`.
774
0
    pub const fn with_hour_12_is_pm(mut self, value: bool) -> Option<Self> {
775
0
        self.hour_12_is_pm = Some(value);
776
0
        Some(self)
777
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_hour_12_is_pm
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_hour_12_is_pm
778
779
    /// Set the `minute` component and return `self`.
780
0
    pub const fn with_minute(mut self, value: u8) -> Option<Self> {
781
0
        self.minute = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
782
0
        Some(self)
783
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_minute
784
785
    /// Set the `second` component and return `self`.
786
0
    pub const fn with_second(mut self, value: u8) -> Option<Self> {
787
0
        self.second = OptionRangedU8::Some(const_try_opt!(RangedU8::new(value)));
788
0
        Some(self)
789
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_second
790
791
    /// Set the `subsecond` component and return `self`.
792
0
    pub const fn with_subsecond(mut self, value: u32) -> Option<Self> {
793
0
        self.subsecond = OptionRangedU32::Some(const_try_opt!(RangedU32::new(value)));
794
0
        Some(self)
795
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_subsecond
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_subsecond
796
797
    /// Set the `offset_hour` component and return `self`.
798
0
    pub const fn with_offset_hour(mut self, value: i8) -> Option<Self> {
799
0
        self.offset_hour = OptionRangedI8::Some(const_try_opt!(RangedI8::new(value)));
800
0
        Some(self)
801
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_hour
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_hour
802
803
    /// Set the `offset_minute` component and return `self`.
804
    #[doc(hidden)]
805
    #[deprecated(
806
        since = "0.3.8",
807
        note = "use `parsed.with_offset_minute_signed()` instead"
808
    )]
809
0
    pub const fn with_offset_minute(self, value: u8) -> Option<Self> {
810
0
        if value > i8::MAX as u8 {
811
0
            None
812
        } else {
813
0
            self.with_offset_minute_signed(value as i8)
814
        }
815
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_minute
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_minute
816
817
    /// Set the `offset_minute` component and return `self`.
818
0
    pub const fn with_offset_minute_signed(mut self, value: i8) -> Option<Self> {
819
0
        self.offset_minute = OptionRangedI8::Some(const_try_opt!(RangedI8::new(value)));
820
0
        Some(self)
821
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_minute_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_minute_signed
822
823
    /// Set the `offset_minute` component and return `self`.
824
    #[doc(hidden)]
825
    #[deprecated(
826
        since = "0.3.8",
827
        note = "use `parsed.with_offset_second_signed()` instead"
828
    )]
829
0
    pub const fn with_offset_second(self, value: u8) -> Option<Self> {
830
0
        if value > i8::MAX as u8 {
831
0
            None
832
        } else {
833
0
            self.with_offset_second_signed(value as i8)
834
        }
835
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_second
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_second
836
837
    /// Set the `offset_second` component and return `self`.
838
0
    pub const fn with_offset_second_signed(mut self, value: i8) -> Option<Self> {
839
0
        self.offset_second = OptionRangedI8::Some(const_try_opt!(RangedI8::new(value)));
840
0
        Some(self)
841
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_second_signed
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_offset_second_signed
842
843
    /// Set the `unix_timestamp_nanos` component and return `self`.
844
0
    pub const fn with_unix_timestamp_nanos(mut self, value: i128) -> Option<Self> {
845
0
        self.unix_timestamp_nanos = OptionRangedI128::Some(const_try_opt!(RangedI128::new(value)));
846
0
        Some(self)
847
0
    }
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_unix_timestamp_nanos
Unexecuted instantiation: <time::parsing::parsed::Parsed>::with_unix_timestamp_nanos
848
}
849
850
impl TryFrom<Parsed> for Date {
851
    type Error = error::TryFromParsed;
852
853
0
    fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> {
854
        /// Match on the components that need to be present.
855
        macro_rules! match_ {
856
            (_ => $catch_all:expr $(,)?) => {
857
                $catch_all
858
            };
859
            (($($name:ident),* $(,)?) => $arm:expr, $($rest:tt)*) => {
860
                if let ($(Some($name)),*) = ($(parsed.$name()),*) {
861
                    $arm
862
                } else {
863
                    match_!($($rest)*)
864
                }
865
            };
866
        }
867
868
        /// Get the value needed to adjust the ordinal day for Sunday and Monday-based week
869
        /// numbering.
870
0
        const fn adjustment(year: i32) -> i16 {
871
            // Safety: `ordinal` is not zero.
872
0
            match unsafe { Date::__from_ordinal_date_unchecked(year, 1) }.weekday() {
873
0
                Weekday::Monday => 7,
874
0
                Weekday::Tuesday => 1,
875
0
                Weekday::Wednesday => 2,
876
0
                Weekday::Thursday => 3,
877
0
                Weekday::Friday => 4,
878
0
                Weekday::Saturday => 5,
879
0
                Weekday::Sunday => 6,
880
            }
881
0
        }
Unexecuted instantiation: <time::date::Date as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from::adjustment
Unexecuted instantiation: <time::date::Date as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from::adjustment
882
883
        // If we do not have the year but we have *both* the century and the last two digits, we can
884
        // construct the year. Likewise for the ISO year.
885
0
        if let (None, Some(century), Some(is_negative), Some(last_two)) = (
886
0
            parsed.year(),
887
0
            parsed.year_century(),
888
0
            parsed.year_century_is_negative(),
889
0
            parsed.year_last_two(),
890
        ) {
891
0
            let year = if is_negative {
892
0
                100 * century.extend::<i32>() - last_two.cast_signed().extend::<i32>()
893
            } else {
894
0
                100 * century.extend::<i32>() + last_two.cast_signed().extend::<i32>()
895
            };
896
0
            parsed.year = OptionRangedI32::from(RangedI32::new(year));
897
0
        }
898
0
        if let (None, Some(century), Some(is_negative), Some(last_two)) = (
899
0
            parsed.iso_year(),
900
0
            parsed.iso_year_century(),
901
0
            parsed.iso_year_century_is_negative(),
902
0
            parsed.iso_year_last_two(),
903
        ) {
904
0
            let iso_year = if is_negative {
905
0
                100 * century.extend::<i32>() - last_two.cast_signed().extend::<i32>()
906
            } else {
907
0
                100 * century.extend::<i32>() + last_two.cast_signed().extend::<i32>()
908
            };
909
0
            parsed.iso_year = OptionRangedI32::from(RangedI32::new(iso_year));
910
0
        }
911
912
0
        match_! {
913
0
            (year, ordinal) => Ok(Self::from_ordinal_date(year, ordinal.get())?),
914
0
            (year, month, day) => Ok(Self::from_calendar_date(year, month, day.get())?),
915
0
            (iso_year, iso_week_number, weekday) => Ok(Self::from_iso_week_date(
916
0
                iso_year,
917
0
                iso_week_number.get(),
918
0
                weekday,
919
0
            )?),
920
0
            (year, sunday_week_number, weekday) => Ok(Self::from_ordinal_date(
921
0
                year,
922
0
                (sunday_week_number.cast_signed().extend::<i16>() * 7
923
0
                    + weekday.number_days_from_sunday().cast_signed().extend::<i16>()
924
0
                    - adjustment(year)
925
0
                    + 1).cast_unsigned(),
926
0
            )?),
927
0
            (year, monday_week_number, weekday) => Ok(Self::from_ordinal_date(
928
0
                year,
929
0
                (monday_week_number.cast_signed().extend::<i16>() * 7
930
0
                    + weekday.number_days_from_monday().cast_signed().extend::<i16>()
931
0
                    - adjustment(year)
932
0
                    + 1).cast_unsigned(),
933
0
            )?),
934
0
            _ => Err(InsufficientInformation),
935
        }
936
0
    }
Unexecuted instantiation: <time::date::Date as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
Unexecuted instantiation: <time::date::Date as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
937
}
938
939
impl TryFrom<Parsed> for Time {
940
    type Error = error::TryFromParsed;
941
942
0
    fn try_from(parsed: Parsed) -> Result<Self, Self::Error> {
943
0
        let hour = match (parsed.hour_24(), parsed.hour_12(), parsed.hour_12_is_pm()) {
944
0
            (Some(hour), _, _) => hour,
945
0
            (_, Some(hour), Some(false)) if hour.get() == 12 => 0,
946
0
            (_, Some(hour), Some(true)) if hour.get() == 12 => 12,
947
0
            (_, Some(hour), Some(false)) => hour.get(),
948
0
            (_, Some(hour), Some(true)) => hour.get() + 12,
949
0
            _ => return Err(InsufficientInformation),
950
        };
951
952
0
        if parsed.hour_24().is_none()
953
0
            && parsed.hour_12().is_some()
954
0
            && parsed.hour_12_is_pm().is_some()
955
0
            && parsed.minute().is_none()
956
0
            && parsed.second().is_none()
957
0
            && parsed.subsecond().is_none()
958
        {
959
0
            return Ok(Self::from_hms_nano(hour, 0, 0, 0)?);
960
0
        }
961
962
        // Reject combinations such as hour-second with minute omitted.
963
0
        match (parsed.minute(), parsed.second(), parsed.subsecond()) {
964
0
            (None, None, None) => Ok(Self::from_hms_nano(hour, 0, 0, 0)?),
965
0
            (Some(minute), None, None) => Ok(Self::from_hms_nano(hour, minute, 0, 0)?),
966
0
            (Some(minute), Some(second), None) => Ok(Self::from_hms_nano(hour, minute, second, 0)?),
967
0
            (Some(minute), Some(second), Some(subsecond)) => {
968
0
                Ok(Self::from_hms_nano(hour, minute, second, subsecond)?)
969
            }
970
0
            _ => Err(InsufficientInformation),
971
        }
972
0
    }
Unexecuted instantiation: <time::time::Time as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
Unexecuted instantiation: <time::time::Time as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
973
}
974
975
0
fn utc_offset_try_from_parsed<const REQUIRED: bool>(
976
0
    parsed: Parsed,
977
0
) -> Result<UtcOffset, error::TryFromParsed> {
978
0
    let hour = match (REQUIRED, parsed.offset_hour()) {
979
        // An offset is required, but the hour is missing. Return an error.
980
0
        (true, None) => return Err(InsufficientInformation),
981
        // An offset is not required (e.g. for `UtcDateTime`). As the hour is missing, minutes and
982
        // seconds are not parsed. This is UTC.
983
0
        (false, None) => return Ok(UtcOffset::UTC),
984
        // Any other situation has an hour present.
985
0
        (_, Some(hour)) => hour,
986
    };
987
0
    let minute = parsed.offset_minute_signed();
988
    // Force `second` to be `None` if `minute` is `None`.
989
0
    let second = minute.and_then(|_| parsed.offset_second_signed());
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<false>::{closure#0}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<true>::{closure#0}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<false>::{closure#0}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<true>::{closure#0}
990
991
0
    let minute = minute.unwrap_or(0);
992
0
    let second = second.unwrap_or(0);
993
994
0
    UtcOffset::from_hms(hour, minute, second).map_err(|mut err| {
995
        // Provide the user a more accurate error.
996
0
        if err.name == "hours" {
997
0
            err.name = "offset hour";
998
0
        } else if err.name == "minutes" {
999
0
            err.name = "offset minute";
1000
0
        } else if err.name == "seconds" {
1001
0
            err.name = "offset second";
1002
0
        }
1003
0
        err.into()
1004
0
    })
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<false>::{closure#1}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<true>::{closure#1}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<false>::{closure#1}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<true>::{closure#1}
1005
0
}
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<false>
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<true>
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<false>
Unexecuted instantiation: time::parsing::parsed::utc_offset_try_from_parsed::<true>
1006
1007
impl TryFrom<Parsed> for UtcOffset {
1008
    type Error = error::TryFromParsed;
1009
1010
0
    fn try_from(parsed: Parsed) -> Result<Self, Self::Error> {
1011
0
        utc_offset_try_from_parsed::<true>(parsed)
1012
0
    }
Unexecuted instantiation: <time::utc_offset::UtcOffset as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
Unexecuted instantiation: <time::utc_offset::UtcOffset as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
1013
}
1014
1015
impl TryFrom<Parsed> for PrimitiveDateTime {
1016
    type Error = error::TryFromParsed;
1017
1018
0
    fn try_from(parsed: Parsed) -> Result<Self, Self::Error> {
1019
0
        Ok(Self::new(parsed.try_into()?, parsed.try_into()?))
1020
0
    }
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
Unexecuted instantiation: <time::primitive_date_time::PrimitiveDateTime as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
1021
}
1022
1023
impl TryFrom<Parsed> for UtcDateTime {
1024
    type Error = error::TryFromParsed;
1025
1026
0
    fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> {
1027
0
        if let Some(timestamp) = parsed.unix_timestamp_nanos() {
1028
0
            let mut value = Self::from_unix_timestamp_nanos(timestamp)?;
1029
0
            if let Some(subsecond) = parsed.subsecond() {
1030
0
                value = value.replace_nanosecond(subsecond)?;
1031
0
            }
1032
0
            return Ok(value);
1033
0
        }
1034
1035
        // Some well-known formats explicitly allow leap seconds. We don't currently support them,
1036
        // so treat it as the nearest preceding moment that can be represented. Because leap seconds
1037
        // always fall at the end of a month UTC, reject any that are at other times.
1038
0
        let leap_second_input = if parsed.leap_second_allowed && parsed.second() == Some(60) {
1039
0
            if parsed.set_second(59).is_none() {
1040
0
                bug!("59 is a valid second");
1041
0
            }
1042
0
            if parsed.set_subsecond(999_999_999).is_none() {
1043
0
                bug!("999_999_999 is a valid subsecond");
1044
0
            }
1045
0
            true
1046
        } else {
1047
0
            false
1048
        };
1049
1050
0
        let dt = OffsetDateTime::new_in_offset(
1051
0
            Date::try_from(parsed)?,
1052
0
            Time::try_from(parsed)?,
1053
0
            utc_offset_try_from_parsed::<false>(parsed)?,
1054
        )
1055
0
        .to_utc();
1056
1057
0
        if leap_second_input && !dt.is_valid_leap_second_stand_in() {
1058
0
            return Err(error::TryFromParsed::ComponentRange(
1059
0
                error::ComponentRange {
1060
0
                    name: "second",
1061
0
                    minimum: 0,
1062
0
                    maximum: 59,
1063
0
                    value: 60,
1064
0
                    conditional_message: Some("because leap seconds are not supported"),
1065
0
                },
1066
0
            ));
1067
0
        }
1068
0
        Ok(dt)
1069
0
    }
Unexecuted instantiation: <time::utc_date_time::UtcDateTime as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
Unexecuted instantiation: <time::utc_date_time::UtcDateTime as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
1070
}
1071
1072
impl TryFrom<Parsed> for OffsetDateTime {
1073
    type Error = error::TryFromParsed;
1074
1075
0
    fn try_from(mut parsed: Parsed) -> Result<Self, Self::Error> {
1076
0
        if let Some(timestamp) = parsed.unix_timestamp_nanos() {
1077
0
            let mut value = Self::from_unix_timestamp_nanos(timestamp)?;
1078
0
            if let Some(subsecond) = parsed.subsecond() {
1079
0
                value = value.replace_nanosecond(subsecond)?;
1080
0
            }
1081
0
            return Ok(value);
1082
0
        }
1083
1084
        // Some well-known formats explicitly allow leap seconds. We don't currently support them,
1085
        // so treat it as the nearest preceding moment that can be represented. Because leap seconds
1086
        // always fall at the end of a month UTC, reject any that are at other times.
1087
0
        let leap_second_input = if parsed.leap_second_allowed && parsed.second() == Some(60) {
1088
0
            if parsed.set_second(59).is_none() {
1089
0
                bug!("59 is a valid second");
1090
0
            }
1091
0
            if parsed.set_subsecond(999_999_999).is_none() {
1092
0
                bug!("999_999_999 is a valid subsecond");
1093
0
            }
1094
0
            true
1095
        } else {
1096
0
            false
1097
        };
1098
1099
0
        let dt = Self::new_in_offset(
1100
0
            Date::try_from(parsed)?,
1101
0
            Time::try_from(parsed)?,
1102
0
            UtcOffset::try_from(parsed)?,
1103
        );
1104
1105
0
        if leap_second_input && !dt.is_valid_leap_second_stand_in() {
1106
0
            return Err(error::TryFromParsed::ComponentRange(
1107
0
                error::ComponentRange {
1108
0
                    name: "second",
1109
0
                    minimum: 0,
1110
0
                    maximum: 59,
1111
0
                    value: 60,
1112
0
                    conditional_message: Some("because leap seconds are not supported"),
1113
0
                },
1114
0
            ));
1115
0
        }
1116
0
        Ok(dt)
1117
0
    }
Unexecuted instantiation: <time::offset_date_time::OffsetDateTime as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
Unexecuted instantiation: <time::offset_date_time::OffsetDateTime as core::convert::TryFrom<time::parsing::parsed::Parsed>>::try_from
1118
}