]> git.proxmox.com Git - rustc.git/blob - vendor/time-macros/src/offset.rs
New upstream version 1.72.1+dfsg1
[rustc.git] / vendor / time-macros / src / offset.rs
1 use std::iter::Peekable;
2
3 use proc_macro::{token_stream, Span, TokenTree};
4 use time_core::convert::*;
5
6 use crate::helpers::{consume_any_ident, consume_number, consume_punct};
7 use crate::to_tokens::ToTokenTree;
8 use crate::Error;
9
10 pub(crate) struct Offset {
11 pub(crate) hours: i8,
12 pub(crate) minutes: i8,
13 pub(crate) seconds: i8,
14 }
15
16 pub(crate) fn parse(chars: &mut Peekable<token_stream::IntoIter>) -> Result<Offset, Error> {
17 if consume_any_ident(&["utc", "UTC"], chars).is_ok() {
18 return Ok(Offset {
19 hours: 0,
20 minutes: 0,
21 seconds: 0,
22 });
23 }
24
25 let sign = if consume_punct('+', chars).is_ok() {
26 1
27 } else if consume_punct('-', chars).is_ok() {
28 -1
29 } else if let Some(tree) = chars.next() {
30 return Err(Error::UnexpectedToken { tree });
31 } else {
32 return Err(Error::MissingComponent {
33 name: "sign",
34 span_start: None,
35 span_end: None,
36 });
37 };
38
39 let (hours_span, hours) = consume_number::<i8>("hour", chars)?;
40 let (mut minutes_span, mut minutes) = (Span::mixed_site(), 0);
41 let (mut seconds_span, mut seconds) = (Span::mixed_site(), 0);
42
43 if consume_punct(':', chars).is_ok() {
44 let min = consume_number::<i8>("minute", chars)?;
45 minutes_span = min.0;
46 minutes = min.1;
47
48 if consume_punct(':', chars).is_ok() {
49 let sec = consume_number::<i8>("second", chars)?;
50 seconds_span = sec.0;
51 seconds = sec.1;
52 }
53 }
54
55 if hours >= 24 {
56 Err(Error::InvalidComponent {
57 name: "hour",
58 value: hours.to_string(),
59 span_start: Some(hours_span),
60 span_end: Some(hours_span),
61 })
62 } else if minutes >= Minute.per(Hour) as _ {
63 Err(Error::InvalidComponent {
64 name: "minute",
65 value: minutes.to_string(),
66 span_start: Some(minutes_span),
67 span_end: Some(minutes_span),
68 })
69 } else if seconds >= Second.per(Minute) as _ {
70 Err(Error::InvalidComponent {
71 name: "second",
72 value: seconds.to_string(),
73 span_start: Some(seconds_span),
74 span_end: Some(seconds_span),
75 })
76 } else {
77 Ok(Offset {
78 hours: sign * hours,
79 minutes: sign * minutes,
80 seconds: sign * seconds,
81 })
82 }
83 }
84
85 impl ToTokenTree for Offset {
86 fn into_token_tree(self) -> TokenTree {
87 quote_group! {{
88 const OFFSET: ::time::UtcOffset = ::time::UtcOffset::__from_hms_unchecked(
89 #(self.hours),
90 #(self.minutes),
91 #(self.seconds),
92 );
93 OFFSET
94 }}
95 }
96 }