1 use std
::iter
::Peekable
;
3 use proc_macro
::{token_stream, Span, TokenTree}
;
4 use time_core
::convert
::*;
6 use crate::helpers
::{consume_any_ident, consume_number, consume_punct}
;
7 use crate::to_tokens
::ToTokenTree
;
10 pub(crate) struct Offset
{
12 pub(crate) minutes
: i8,
13 pub(crate) seconds
: i8,
16 pub(crate) fn parse(chars
: &mut Peekable
<token_stream
::IntoIter
>) -> Result
<Offset
, Error
> {
17 if consume_any_ident(&["utc", "UTC"], chars
).is_ok() {
25 let sign
= if consume_punct('
+'
, chars
).is_ok() {
27 } else if consume_punct('
-'
, chars
).is_ok() {
29 } else if let Some(tree
) = chars
.next() {
30 return Err(Error
::UnexpectedToken { tree }
);
32 return Err(Error
::MissingComponent
{
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);
43 if consume_punct('
:'
, chars
).is_ok() {
44 let min
= consume_number
::<i8>("minute", chars
)?
;
48 if consume_punct('
:'
, chars
).is_ok() {
49 let sec
= consume_number
::<i8>("second", chars
)?
;
56 Err(Error
::InvalidComponent
{
58 value
: hours
.to_string(),
59 span_start
: Some(hours_span
),
60 span_end
: Some(hours_span
),
62 } else if minutes
>= Minute
.per(Hour
) as _
{
63 Err(Error
::InvalidComponent
{
65 value
: minutes
.to_string(),
66 span_start
: Some(minutes_span
),
67 span_end
: Some(minutes_span
),
69 } else if seconds
>= Second
.per(Minute
) as _
{
70 Err(Error
::InvalidComponent
{
72 value
: seconds
.to_string(),
73 span_start
: Some(seconds_span
),
74 span_end
: Some(seconds_span
),
79 minutes
: sign
* minutes
,
80 seconds
: sign
* seconds
,
85 impl ToTokenTree
for Offset
{
86 fn into_token_tree(self) -> TokenTree
{
88 const OFFSET
: ::time
::UtcOffset
= ::time
::UtcOffset
::__from_hms_unchecked(