-- | Parsers for input data values.
module ConditionalRestriction.Parse.InputDataParser
  ( pValue,
    pBool,
    pNum,
    pTime,
  )
where

import ConditionalRestriction.Internal.Parse.ParserLib
  ( Parser,
    bint,
    dbl,
    str,
  )
import ConditionalRestriction.Parse.InputData (Value (..))
import Control.Applicative (Alternative ((<|>)))
import Control.Monad (replicateM)
import Data.Hourglass
  ( Date (Date),
    DateTime (DateTime),
    TimeOfDay (TimeOfDay),
  )

-- | Parses 'Value's. See 'pBool', 'pNum' and 'pTime' for formats.
pValue :: Parser String Value
pValue :: Parser String Value
pValue = Parser String Value
pBool forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser String Value
pTime forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser String Value
pNum

-- | Parses boolean values. Possible values are @"true"@ and @"false"@.
pBool :: Parser String Value
pBool :: Parser String Value
pBool =
  Bool -> Value
VBool Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String String
str String
"true"
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Bool -> Value
VBool Bool
False forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> Parser String String
str String
"false"

-- | Parses numbers. Values can be with or without decimal places, i.e. @"5"@ or @"5.34"@.
pNum :: Parser String Value
pNum :: Parser String Value
pNum = Double -> Value
VNum forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String Double
dbl

-- | Parses time and date in the format @"YYYY-MM-DD hh:mm"@.
pTime :: Parser String Value
pTime :: Parser String Value
pTime = DateTime -> Value
VTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Date -> TimeOfDay -> DateTime
DateTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String Date
p_date forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser String String
str String
" " forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String TimeOfDay
p_time))
  where
    p_date :: Parser String Date
p_date = Int -> Month -> Int -> Date
Date forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser String Int
p_year forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser String String
str String
"-" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String Month
p_month) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser String String
str String
"-" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser String Int
p_day)
    p_time :: Parser String TimeOfDay
p_time = (\Int
h Int
m -> Hours -> Minutes -> Seconds -> NanoSeconds -> TimeOfDay
TimeOfDay (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
h) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
m) Seconds
0 NanoSeconds
0) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser String Int
bint Int
24 forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> Parser String String
str String
":" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> Parser String Int
bint Int
59)
    p_year :: Parser String Int
p_year = Int -> Parser String Int
bint Int
9999
    p_month :: Parser String Month
p_month = forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Int
x -> Int
x forall a. Num a => a -> a -> a
- Int
1) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser String Int
bint Int
12
    p_day :: Parser String Int
p_day = Int -> Parser String Int
bint Int
31
    concat :: [a] -> a -> [a]
concat [a]
s a
c = [a]
s forall a. [a] -> [a] -> [a]
++ [a
c]
    pack :: a -> a -> [a]
pack a
x a
y = [a
x, a
y]