{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Taskell.Date.RelativeParser
( parseRelative
) where
import ClassyPrelude
import Data.Attoparsec.Text
import Data.Time.Clock (addUTCTime)
import Utility.Parser (lexeme)
minute :: Int
minute = 60
hour :: Int
hour = minute * 60
day :: Int
day = hour * 24
week :: Int
week = day * 7
periodP :: Char -> Parser Int
periodP c = lexeme decimal <* char c
wP :: Parser Int
wP = (* week) <$> periodP 'w'
dP :: Parser Int
dP = (* day) <$> periodP 'd'
hP :: Parser Int
hP = (* hour) <$> periodP 'h'
mP :: Parser Int
mP = (* minute) <$> periodP 'm'
sP :: Parser Int
sP = periodP 's'
relativeP :: UTCTime -> Parser (Maybe UTCTime)
relativeP now =
lexeme $ do
period <- fromIntegral . sum <$> many1 (sP <|> mP <|> hP <|> dP <|> wP)
pure $ Just (addUTCTime period now)
parseRelative :: UTCTime -> Text -> Either Text UTCTime
parseRelative now text =
case parseOnly (relativeP now) text of
Right (Just time) -> Right time
_ -> Left "Could not parse date."