time_macros/
datetime.rs

1use std::iter::Peekable;
2
3use proc_macro::{token_stream, TokenStream};
4
5use crate::date::Date;
6use crate::error::Error;
7use crate::offset::Offset;
8use crate::time::Time;
9use crate::to_tokens::ToTokenStream;
10use crate::{date, offset, time};
11
12pub(crate) struct DateTime {
13    date: Date,
14    time: Time,
15    offset: Option<Offset>,
16}
17
18pub(crate) fn parse(chars: &mut Peekable<token_stream::IntoIter>) -> Result<DateTime, Error> {
19    let date = date::parse(chars)?;
20    let time = time::parse(chars)?;
21    let offset = match offset::parse(chars) {
22        Ok(offset) => Some(offset),
23        Err(Error::UnexpectedEndOfInput | Error::MissingComponent { name: "sign", .. }) => None,
24        Err(err) => return Err(err),
25    };
26
27    if let Some(token) = chars.peek() {
28        return Err(Error::UnexpectedToken {
29            tree: token.clone(),
30        });
31    }
32
33    Ok(DateTime { date, time, offset })
34}
35
36impl ToTokenStream for DateTime {
37    fn append_to(self, ts: &mut TokenStream) {
38        let maybe_offset = match self.offset {
39            Some(offset) => {
    use proc_macro::*;
    let mut ts = TokenStream::new();
    let ts_mut = &mut ts;
    ts_mut.extend([TokenTree::from(Punct::new('.', Spacing::Alone))]);
    ;
    ts_mut.extend([TokenTree::from(Ident::new(&"assume_offset",
                        Span::mixed_site()))]);
    ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            crate::to_tokens::ToTokenStream::append_to(offset, ts_mut);
                            ;
                            ts
                        }))]);
    ;
    ts
}quote_! { .assume_offset(#S(offset)) },
40            None => proc_macro::TokenStream::new()quote_! {},
41        };
42
43        {
    use proc_macro::*;
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"time", Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"PrimitiveDateTime",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"new", Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            crate::to_tokens::ToTokenStream::append_to(self.date,
                                ts_mut);
                            ts_mut.extend([TokenTree::from(Punct::new(',',
                                                Spacing::Alone))]);
                            ;
                            crate::to_tokens::ToTokenStream::append_to(self.time,
                                ts_mut);
                            ts_mut.extend([TokenTree::from(Punct::new(',',
                                                Spacing::Alone))]);
                            ;
                            ;
                            ts
                        }))]);
    crate::to_tokens::ToTokenStream::append_to(maybe_offset, ts);
    ;
}quote_append! { ts
44            ::time::PrimitiveDateTime::new(
45                #S(self.date),
46                #S(self.time),
47            ) #S(maybe_offset)
48        }
49    }
50}