Repository navigation
Expand file tree
/
Copy pathEffect.hs
More file actions
204 lines (175 loc) · 5.3 KB
/
Copy pathEffect.hs
File metadata and controls
204 lines (175 loc) · 5.3 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE FlexibleInstances #-}
module Effect
( Effect
, EffectF(..)
, Selector(..)
, Condition(..)
, Order(..)
, say
, logMsg
, createEntity
, getEntityById
, deleteEntityById
, updateEntityById
, selectEntities
, deleteEntities
, httpRequest
, now
, timeout
, errorEff
, twitchApiRequest
, listen
, periodicEffect
, periodicEffect'
, twitchCommand
, randomMarkov
, reloadMarkov
, githubApiRequest
, randomEff
) where
import Control.Monad.Catch
import qualified Data.ByteString.Lazy.Char8 as B8
import Data.Proxy
import qualified Data.Text as T
import Data.Time
import Entity
import Free
import Network.HTTP.Simple (Request, Response)
import Property
import Transport
data Condition
= PropertyEquals T.Text
Property
| PropertyGreater T.Text
Property
| PropertyMissing T.Text
| PropertyTextLike T.Text
T.Text
| ConditionAnd [Condition]
deriving (Show)
data Order
= Asc
| Desc
deriving (Show)
data Selector
= All
| Filter Condition
Selector
| Shuffle Selector
| Take Int
Selector
| SortBy T.Text
Order
Selector
deriving (Show)
data EffectF s
= Say Channel
T.Text
s
| LogMsg T.Text
s
| ErrorEff T.Text
| CreateEntity T.Text
Properties
(Entity Properties -> s)
| GetEntityById T.Text
Int
(Maybe (Entity Properties) -> s)
| DeleteEntityById T.Text
Int
s
| UpdateEntityById (Entity Properties)
(Maybe (Entity Properties) -> s)
| SelectEntities T.Text
Selector
([Entity Properties] -> s)
| DeleteEntities T.Text
Selector
(Int -> s)
| Now (UTCTime -> s)
| HttpRequest Request
(Response B8.ByteString -> s)
| TwitchApiRequest Request
(Response B8.ByteString -> s)
| GitHubApiRequest Request
(Response B8.ByteString -> s)
| TimeoutEff Integer
(Maybe Channel)
(Effect ())
s
| Listen (Effect ())
([T.Text] -> s)
| TwitchCommand Channel
T.Text
[T.Text]
s
| RandomMarkov (Maybe T.Text -> s)
| ReloadMarkov (Maybe T.Text -> s)
| RandomEff (Int, Int)
(Int -> s)
deriving (Functor)
type Effect = Free EffectF
instance MonadThrow Effect where
throwM :: Exception e => e -> Effect a
throwM = errorEff . T.pack . displayException
say :: Channel -> T.Text -> Effect ()
say channel msg = liftF $ Say channel msg ()
logMsg :: T.Text -> Effect ()
logMsg msg = liftF $ LogMsg msg ()
createEntity :: IsEntity e => Proxy e -> e -> Effect (Entity e)
createEntity proxy entity =
liftF (CreateEntity (nameOfEntity proxy) (toProperties entity) id) >>=
fromEntityProperties
getEntityById :: IsEntity e => Proxy e -> Int -> Effect (Maybe (Entity e))
getEntityById proxy ident =
fmap (>>= fromEntityProperties) $
liftF $ GetEntityById (nameOfEntity proxy) ident id
deleteEntityById :: IsEntity e => Proxy e -> Int -> Effect ()
deleteEntityById proxy ident =
liftF $ DeleteEntityById (nameOfEntity proxy) ident ()
updateEntityById :: IsEntity e => Entity e -> Effect (Maybe (Entity e))
updateEntityById entity =
fmap (>>= fromEntityProperties) $
liftF $ UpdateEntityById (toProperties <$> entity) id
selectEntities :: IsEntity e => Proxy e -> Selector -> Effect [Entity e]
selectEntities proxy selector =
fmap (>>= fromEntityProperties) $
liftF $ SelectEntities (nameOfEntity proxy) selector id
deleteEntities :: IsEntity e => Proxy e -> Selector -> Effect Int
deleteEntities proxy selector =
liftF $ DeleteEntities (nameOfEntity proxy) selector id
now :: Effect UTCTime
now = liftF $ Now id
httpRequest :: Request -> Effect (Response B8.ByteString)
httpRequest request = liftF $ HttpRequest request id
twitchApiRequest :: Request -> Effect (Response B8.ByteString)
twitchApiRequest request = liftF $ TwitchApiRequest request id
githubApiRequest :: Request -> Effect (Response B8.ByteString)
githubApiRequest request = liftF $ GitHubApiRequest request id
timeout :: Integer -> Maybe Channel -> Effect () -> Effect ()
timeout t c e = liftF $ TimeoutEff t c e ()
errorEff :: T.Text -> Effect a
errorEff t = liftF $ ErrorEff t
listen :: Effect () -> Effect [T.Text]
listen effect = liftF $ Listen effect id
periodicEffect :: Integer -> Maybe Channel -> Effect () -> Effect ()
periodicEffect period channel effect = do
effect
timeout period channel $ periodicEffect period channel effect
periodicEffect' :: Maybe Channel -> Effect (Maybe Integer) -> Effect ()
periodicEffect' channel effect = do
period' <- effect
maybe
(return ())
(\period -> timeout period channel $ periodicEffect' channel effect)
period'
twitchCommand :: Channel -> T.Text -> [T.Text] -> Effect ()
twitchCommand channel name args = liftF $ TwitchCommand channel name args ()
randomMarkov :: Effect (Maybe T.Text)
randomMarkov = liftF $ RandomMarkov id
reloadMarkov :: Effect (Maybe T.Text)
reloadMarkov = liftF $ ReloadMarkov id
randomEff :: (Int, Int) -> Effect Int
randomEff range = liftF $ RandomEff range id