use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
use fastobo_derive_internal::FromStr;
use crate::ast::*;
use crate::error::SyntaxError;
use crate::parser::Cache;
use crate::parser::FromPair;
use crate::syntax::pest::iterators::Pair;
use crate::syntax::Rule;
#[derive(Clone, Debug, FromStr, Hash, PartialOrd, Ord, Eq, PartialEq)]
pub enum CreationDate {
Date(Box<IsoDate>),
DateTime(Box<IsoDateTime>),
}
impl AsRef<IsoDate> for CreationDate {
fn as_ref(&self) -> &IsoDate {
match self {
CreationDate::Date(d) => d,
CreationDate::DateTime(dt) => dt.date(),
}
}
}
impl Display for CreationDate {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
match self {
CreationDate::Date(d) => d.fmt(f),
CreationDate::DateTime(d) => d.fmt(f),
}
}
}
impl Date for CreationDate {
fn year(&self) -> u16 {
<Self as AsRef<IsoDate>>::as_ref(self).year()
}
fn month(&self) -> u8 {
<Self as AsRef<IsoDate>>::as_ref(self).month()
}
fn day(&self) -> u8 {
<Self as AsRef<IsoDate>>::as_ref(self).day()
}
}
impl From<Box<IsoDateTime>> for CreationDate {
fn from(b: Box<IsoDateTime>) -> Self {
CreationDate::DateTime(b)
}
}
impl From<Box<IsoDate>> for CreationDate {
fn from(b: Box<IsoDate>) -> Self {
CreationDate::Date(b)
}
}
impl From<IsoDate> for CreationDate {
fn from(b: IsoDate) -> Self {
Self::from(Box::new(b))
}
}
impl From<IsoDateTime> for CreationDate {
fn from(b: IsoDateTime) -> Self {
Self::from(Box::new(b))
}
}
impl<'i> FromPair<'i> for CreationDate {
const RULE: Rule = Rule::CreationDate;
unsafe fn from_pair_unchecked(
pair: Pair<'i, Rule>,
cache: &Cache,
) -> Result<Self, SyntaxError> {
let inner = pair.into_inner().next().unwrap();
match inner.as_rule() {
Rule::Iso8601DateTime => IsoDateTime::from_pair(inner, cache).map(From::from),
Rule::Iso8601Date => IsoDate::from_pair(inner, cache).map(From::from),
rule => unreachable!("unexpected rule in CreationDate::from_pair: {:?}", rule),
}
}
}