| 1 | use std::iter::Peekable; | 
| 2 |  | 
|---|
| 3 | use proc_macro::{token_stream, Ident, Span, TokenTree}; | 
|---|
| 4 |  | 
|---|
| 5 | use crate::date::Date; | 
|---|
| 6 | use crate::error::Error; | 
|---|
| 7 | use crate::offset::Offset; | 
|---|
| 8 | use crate::time::Time; | 
|---|
| 9 | use crate::to_tokens::ToTokenTree; | 
|---|
| 10 | use crate::{date, offset, time}; | 
|---|
| 11 |  | 
|---|
| 12 | pub(crate) struct DateTime { | 
|---|
| 13 | date: Date, | 
|---|
| 14 | time: Time, | 
|---|
| 15 | offset: Option<Offset>, | 
|---|
| 16 | } | 
|---|
| 17 |  | 
|---|
| 18 | pub(crate) fn parse(chars: &mut Peekable<token_stream::IntoIter>) -> Result<DateTime, Error> { | 
|---|
| 19 | let date: Date = date::parse(chars)?; | 
|---|
| 20 | let time: Time = time::parse(chars)?; | 
|---|
| 21 | let offset: Option = match offset::parse(chars) { | 
|---|
| 22 | Ok(offset: Offset) => Some(offset), | 
|---|
| 23 | Err(Error::UnexpectedEndOfInput | Error::MissingComponent { name: "sign", .. }) => None, | 
|---|
| 24 | Err(err: Error) => return Err(err), | 
|---|
| 25 | }; | 
|---|
| 26 |  | 
|---|
| 27 | if let Some(token: &TokenTree) = chars.peek() { | 
|---|
| 28 | return Err(Error::UnexpectedToken { | 
|---|
| 29 | tree: token.clone(), | 
|---|
| 30 | }); | 
|---|
| 31 | } | 
|---|
| 32 |  | 
|---|
| 33 | Ok(DateTime { date, time, offset }) | 
|---|
| 34 | } | 
|---|
| 35 |  | 
|---|
| 36 | impl ToTokenTree for DateTime { | 
|---|
| 37 | fn into_token_tree(self) -> TokenTree { | 
|---|
| 38 | let (type_name: Ident, maybe_offset: TokenStream) = match self.offset { | 
|---|
| 39 | Some(offset: Offset) => ( | 
|---|
| 40 | Ident::new(string: "OffsetDateTime", Span::mixed_site()), | 
|---|
| 41 | quote!(.assume_offset(#(offset))), | 
|---|
| 42 | ), | 
|---|
| 43 | None => ( | 
|---|
| 44 | Ident::new(string: "PrimitiveDateTime", Span::mixed_site()), | 
|---|
| 45 | quote!(), | 
|---|
| 46 | ), | 
|---|
| 47 | }; | 
|---|
| 48 |  | 
|---|
| 49 | quote_group! {{ | 
|---|
| 50 | const DATE_TIME: ::time::#(type_name) = ::time::PrimitiveDateTime::new( | 
|---|
| 51 | #(self.date), | 
|---|
| 52 | #(self.time), | 
|---|
| 53 | ) #S(maybe_offset); | 
|---|
| 54 | DATE_TIME | 
|---|
| 55 | }} | 
|---|
| 56 | } | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|