/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 | | } |