summaryrefslogtreecommitdiff
path: root/events/src/Events/Types.hs
blob: 19fccdf84abae151016298807aa63e1e1e102900 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

module Events.Types
       ( TimeRange(..), rangeStart, rangeDuration
       , Event(..), payload, occursWithin
       , EvalCtx(..), ctxVars, ctxEvents, ctxEvent, ctxOccurs
       , Eval, evaluate
       , module Data.Aeson
       , module Data.Time.Clock
       , module Data.Default.Class
       ) where

import Control.Lens.TH
  
import Data.Aeson (Object)

import Data.Time.Clock

import Control.Monad.State.Lazy
import ListT (ListT)
import qualified ListT

import Data.Default.Class

import Data.Monoid
import Control.Monad.Fix
import Control.Lens
import Data.Maybe
import Data.Bool

import Debug.Trace

data TimeRange = TimeRange
                 { _rangeStart :: UTCTime
                 , _rangeDuration :: NominalDiffTime
                 }
makeLenses ''TimeRange

data Event = Event
             { _payload :: Object
             , _occursWithin :: TimeRange -> Bool
             }
makeLenses ''Event

data EvalCtx = EvalCtx
               { _ctxVars :: Object
               , _ctxEvents :: [Object]
               , _ctxEvent :: Maybe Object
               , _ctxOccurs :: Bool
               } deriving (Show)
makeLenses ''EvalCtx

instance Default EvalCtx where
  def = EvalCtx
        { _ctxVars = mempty
        , _ctxEvents = mempty
        , _ctxEvent = Nothing
        , _ctxOccurs = False
        }

type Eval m a = ListT (StateT EvalCtx m) a

evaluate :: MonadFix m => Eval m () -> m [Object]
evaluate x = (^. ctxEvents) <$> mfix x'
  where
    x' = execStateT (ListT.toList x) . resetState -- flip (set ctxEvents) def . catMaybes
    resetState = execState $ do
      ctxEvents <~ bool const (\x y -> x ++ maybe [] pure y) <$> use ctxOccurs <*> use ctxEvents <*> use ctxEvent
      ctxEvent .= def ^. ctxEvent
      ctxOccurs .= def ^. ctxOccurs

instance MonadState s m => MonadState s (ListT m) where
  get = lift get
  put = lift . put