module Mongrel2.Response
( Response
, mkResponse
) where
import Blaze.ByteString.Builder (Builder, toByteString, fromByteString)
import Blaze.Text.Int (integral)
import Data.ByteString (ByteString)
import Data.ByteString.Char8 ()
import Data.List (intersperse)
import Data.Monoid
import Mongrel2.Types (ClientID, UUID)
import qualified Data.ByteString as S
-- | Raw response type.
type Response = ByteString
-- | Build a single space.
buildSpace :: Builder
buildSpace = fromByteString " "
-- | Build a UUID.
buildUUID :: UUID -> Builder
buildUUID = fromByteString
-- | Build a netstring from a builder.
buildNetstring :: Builder -> Builder
buildNetstring b =
-- TODO: Is it possible to find the length without "forcing" the Builder?
mconcat [ integral $ S.length s
, fromByteString ":"
, fromByteString s
]
where
s = toByteString b
-- | Build client ID list.
buildClientIDList :: [ClientID] -> Builder
buildClientIDList cids =
mconcat $ intersperse buildSpace $ map integral cids
-- | Build a response from a server UUID, a list of
-- client IDs and a response body builder.
mkResponse :: UUID -> [ClientID] -> Builder -> Response
mkResponse uuid clientIDs bodyBuilder =
toByteString $ mconcat [ buildUUID uuid
, buildSpace
, buildNetstring $ buildClientIDList clientIDs
, fromByteString ", "
, bodyBuilder ]