/
Json.purs
76 lines (62 loc) 路 2.32 KB
/
Json.purs
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
module HTTPurple.Json
( JsonDecoder(..)
, JsonEncoder(..)
, fromJson
, fromJsonE
, jsonHeader
, jsonHeaders
, toJson
) where
import Prelude
import Control.Monad.Cont (ContT(..))
import Data.Either (Either, either)
import Data.Function as Function
import Data.Newtype (class Newtype, un)
import Data.Tuple (Tuple(..))
import Effect.Aff.Class (class MonadAff)
import HTTPurple.Body (RequestBody, toString)
import HTTPurple.Headers (Headers, headers)
import HTTPurple.Response (Response, badRequest)
newtype JsonDecoder err json = JsonDecoder (String -> Either err json)
instance Newtype (JsonDecoder err json) (String -> Either err json)
newtype JsonEncoder json = JsonEncoder (json -> String)
instance Newtype (JsonEncoder json) (json -> String)
jsonHeader :: Tuple String String
jsonHeader = Tuple "Content-Type" "application/json"
jsonHeaders :: Headers
jsonHeaders = headers [ jsonHeader ]
fromJsonContinuation ::
forall err json m.
MonadAff m =>
JsonDecoder err json ->
(err -> m Response) ->
RequestBody ->
(json -> m Response) ->
m Response
fromJsonContinuation (JsonDecoder decode) errorHandler body handler = do
bodyStr <- toString body
let
parseJson :: Either err json
parseJson = decode $ bodyStr
either errorHandler handler parseJson
defaultErrorHandler :: forall (err :: Type) (m :: Type -> Type). MonadAff m => err -> m Response
defaultErrorHandler = const $ badRequest ""
-- | Parse the `RequestBody` as json using the provided `JsonDecoder`.
-- | If it fails, the error handler is called.
-- | Returns a continuation
fromJsonE ::
forall (err :: Type) (json :: Type) (m :: Type -> Type).
MonadAff m =>
JsonDecoder err json ->
(err -> m Response) ->
RequestBody ->
ContT Response m json
fromJsonE driver errorHandler body = ContT $ (fromJsonContinuation driver errorHandler body)
-- | Parse the `RequestBody` as json using the provided `JsonDecoder`.
-- | If it fails, an empty bad request is returned
-- | Returns a continuation
fromJson :: forall (err :: Type) (json :: Type) (m :: Type -> Type). MonadAff m => JsonDecoder err json -> RequestBody -> ContT Response m json
fromJson driver = fromJsonE driver defaultErrorHandler
-- | Serialise a type to json using the given driver.
toJson :: forall (json :: Type). JsonEncoder json -> json -> String
toJson = un JsonEncoder >>> Function.apply