{-# LANGUAGE LambdaCase #-} module Nero.Payload ( -- * Payload Payload , payloadText , Encoding , utf8Encoding , HasPayload(..) -- * Body , Body , HasBody(..) -- * Form , Form , _Form , Formed(..) -- * Testing , dummyPayloadForm ) where import Data.ByteString.Lazy (ByteString) import Nero.Prelude import Nero.Param import Nero.Binary -- * Payload -- | Contains the 'Body' and any metadata associated with it. data Payload = PayloadText Encoding Body | PayloadBinary Body | PayloadForm Form deriving (Show,Eq) -- | Indicates a 'Text' encoding. data Encoding = Utf8 | Unknown String deriving (Show,Eq) utf8Encoding :: Encoding utf8Encoding = Utf8 -- Creates a '/text/plain/' 'Payload' with the given 'Encoding' and a 'Body' payloadText :: Encoding -> Body -> Payload payloadText = PayloadText -- | A 'Lens'' for types with a 'Payload'. class HasPayload a where payload :: Lens' a Payload -- * Body -- | It's the main data associated with the 'Payload' of 'Request' or a -- 'Response'. type Body = ByteString -- Can't be made a Lens easily because of putative parsing failures for 'Form' -- TODO: Is it worth making this a traversal? -- | Get the 'Body' for types with one. class HasBody a where body :: a -> Body instance HasBody Payload where body (PayloadText _ b) = b body (PayloadBinary b) = b body (PayloadForm fo) = render fo -- * Form -- | A 'MultiMap' in the context of a form. type Form = MultiMap -- | A 'Prism'' to obtain a 'Form' from a 'Payload' and make 'Payload' from -- a 'Form'. _Form :: Prism' Payload Form _Form = prism' PayloadForm $ \case PayloadForm f -> Just f _ -> Nothing -- | A 'Traversal'' to access a potential 'Form'. class Formed a where form :: Traversal' a Form instance Formed Payload where form = _Form instance Param Payload where param k = form . ix k . traverse -- * Testing -- | A 'Payload' with an empty 'Form' useful for testing. dummyPayloadForm :: Payload dummyPayloadForm = PayloadForm mempty