use std::iter::Peekable; use proc_macro::{token_stream, Ident, Span, TokenTree}; use crate::date::Date; use crate::error::Error; use crate::offset::Offset; use crate::time::Time; use crate::to_tokens::ToTokenTree; use crate::{date, offset, time}; pub(crate) struct DateTime { date: Date, time: Time, offset: Option, } pub(crate) fn parse(chars: &mut Peekable) -> Result { let date = date::parse(chars)?; let time = time::parse(chars)?; let offset = match offset::parse(chars) { Ok(offset) => Some(offset), Err(Error::UnexpectedEndOfInput | Error::MissingComponent { name: "sign", .. }) => None, Err(err) => return Err(err), }; if let Some(token) = chars.peek() { return Err(Error::UnexpectedToken { tree: token.clone(), }); } Ok(DateTime { date, time, offset }) } impl ToTokenTree for DateTime { fn into_token_tree(self) -> TokenTree { let (type_name, maybe_offset) = match self.offset { Some(offset) => ( Ident::new("OffsetDateTime", Span::mixed_site()), quote!(.assume_offset(#(offset))), ), None => ( Ident::new("PrimitiveDateTime", Span::mixed_site()), quote!(), ), }; quote_group! {{ const DATE_TIME: ::time::#(type_name) = ::time::PrimitiveDateTime::new( #(self.date), #(self.time), ) #S(maybe_offset); DATE_TIME }} } }