summaryrefslogtreecommitdiffstats
path: root/third_party/rust/time-macros/src/datetime.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/time-macros/src/datetime.rs')
-rw-r--r--third_party/rust/time-macros/src/datetime.rs57
1 files changed, 57 insertions, 0 deletions
diff --git a/third_party/rust/time-macros/src/datetime.rs b/third_party/rust/time-macros/src/datetime.rs
new file mode 100644
index 0000000000..2d41e9a532
--- /dev/null
+++ b/third_party/rust/time-macros/src/datetime.rs
@@ -0,0 +1,57 @@
+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<Offset>,
+}
+
+pub(crate) fn parse(chars: &mut Peekable<token_stream::IntoIter>) -> Result<DateTime, Error> {
+ 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
+ }}
+ }
+}