-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathForm.purs
More file actions
82 lines (70 loc) · 2.37 KB
/
Form.purs
File metadata and controls
82 lines (70 loc) · 2.37 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
module Hyper.Form
( Form(..)
, optional
, required
, parseForm
) where
import Prelude
import Control.IxMonad (ibind, ipure)
import Control.Monad.Error.Class (throwError)
import Data.Array (head)
import Data.Either (Either(..))
import Data.Generic (class Generic)
import Data.Maybe (Maybe(Just, Nothing), maybe)
import Data.MediaType (MediaType(MediaType))
import Data.MediaType.Common (applicationFormURLEncoded)
import Data.Monoid (class Monoid)
import Data.Newtype (class Newtype, unwrap)
import Data.StrMap (lookup)
import Data.String (Pattern(Pattern), split)
import Data.Tuple (Tuple)
import Data.Tuple as Tuple
import Hyper.Conn (Conn)
import Hyper.Form.Urlencoded (Options) as Urlencoded
import Hyper.Form.Urlencoded (parseUrlencoded)
import Hyper.Middleware (Middleware)
import Hyper.Middleware.Class (getConn)
import Hyper.Request (class Request, class ReadableBody, getRequestData, readBody)
newtype Form = Form (Array (Tuple String (Maybe String)))
derive instance newtypeForm :: Newtype Form _
derive instance genericForm :: Generic Form
derive newtype instance eqForm :: Eq Form
derive newtype instance ordForm :: Ord Form
derive newtype instance showForm :: Show Form
derive newtype instance semigroupForm :: Semigroup Form
derive newtype instance monoidForm :: Monoid Form
optional :: String -> Form -> Maybe String
optional key = do
unwrap
>>> Tuple.lookup key
>>> flip bind id
required :: String -> Form -> Either String String
required key =
optional key
>>> maybe (throwError ("Missing field: " <> key)) pure
parseContentMediaType :: String -> Maybe MediaType
parseContentMediaType = split (Pattern ";")
>>> head
>>> map MediaType
parseForm ∷ forall m req res c
. Monad m
=> Request req m
=> ReadableBody req m String
=> Urlencoded.Options
-> Middleware
m
(Conn req res c)
(Conn req res c)
(Either String Form)
parseForm opts = do
conn <- getConn
{ headers } <- getRequestData
body <- readBody
case lookup "content-type" headers >>= parseContentMediaType of
Nothing ->
ipure (Left "Missing or invalid content-type header.")
Just mediaType | mediaType == applicationFormURLEncoded ->
ipure (Form <$> parseUrlencoded opts body)
Just mediaType ->
ipure (Left ("Cannot parse media of type: " <> show mediaType))
where bind = ibind