Preliminary work to support headers in responses
This commit is contained in:
parent
24e32f194e
commit
642910b3b3
2 changed files with 46 additions and 41 deletions
|
@ -6,6 +6,7 @@
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE PolyKinds #-}
|
{-# LANGUAGE PolyKinds #-}
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
{-# LANGUAGE TypeOperators #-}
|
{-# LANGUAGE TypeOperators #-}
|
||||||
{-# LANGUAGE UndecidableInstances #-}
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
|
@ -83,6 +84,7 @@ import qualified Data.Text.Lazy.Encoding as TextL
|
||||||
import Data.Typeable
|
import Data.Typeable
|
||||||
import GHC.Exts (Constraint)
|
import GHC.Exts (Constraint)
|
||||||
import qualified Network.HTTP.Media as M
|
import qualified Network.HTTP.Media as M
|
||||||
|
import Network.HTTP.Types.Header
|
||||||
import Network.URI (escapeURIString, isUnreserved,
|
import Network.URI (escapeURIString, isUnreserved,
|
||||||
unEscapeString)
|
unEscapeString)
|
||||||
|
|
||||||
|
@ -147,13 +149,13 @@ newtype AcceptHeader = AcceptHeader BS.ByteString
|
||||||
-- > type MyAPI = "path" :> Get '[MyContentType] Int
|
-- > type MyAPI = "path" :> Get '[MyContentType] Int
|
||||||
--
|
--
|
||||||
class Accept ctype => MimeRender ctype a where
|
class Accept ctype => MimeRender ctype a where
|
||||||
toByteString :: Proxy ctype -> a -> ByteString
|
toByteString :: Proxy ctype -> a -> (ResponseHeaders, ByteString)
|
||||||
|
|
||||||
class AllCTRender (list :: [*]) a where
|
class AllCTRender (list :: [*]) a where
|
||||||
-- If the Accept header can be matched, returns (Just) a tuple of the
|
-- If the Accept header can be matched, returns (Just) a tuple of the
|
||||||
-- Content-Type and response (serialization of @a@ into the appropriate
|
-- Content-Type and response (serialization of @a@ into the appropriate
|
||||||
-- mimetype).
|
-- mimetype).
|
||||||
handleAcceptH :: Proxy list -> AcceptHeader -> a -> Maybe (ByteString, ByteString)
|
handleAcceptH :: Proxy list -> AcceptHeader -> a -> Maybe (ByteString, (ResponseHeaders, ByteString))
|
||||||
|
|
||||||
instance ( AllMimeRender ctyps a, IsNonEmpty ctyps
|
instance ( AllMimeRender ctyps a, IsNonEmpty ctyps
|
||||||
) => AllCTRender ctyps a where
|
) => AllCTRender ctyps a where
|
||||||
|
@ -188,18 +190,19 @@ instance ( AllMimeRender ctyps a, IsNonEmpty ctyps
|
||||||
-- >>> type MyAPI = "path" :> ReqBody '[MyContentType] Int :> Get '[JSON] Int
|
-- >>> type MyAPI = "path" :> ReqBody '[MyContentType] Int :> Get '[JSON] Int
|
||||||
--
|
--
|
||||||
class Accept ctype => MimeUnrender ctype a where
|
class Accept ctype => MimeUnrender ctype a where
|
||||||
fromByteString :: Proxy ctype -> ByteString -> Either String a
|
fromByteString :: Proxy ctype -> ResponseHeaders -> ByteString -> Either String a
|
||||||
|
|
||||||
class (IsNonEmpty list) => AllCTUnrender (list :: [*]) a where
|
class (IsNonEmpty list) => AllCTUnrender (list :: [*]) a where
|
||||||
handleCTypeH :: Proxy list
|
handleCTypeH :: Proxy list
|
||||||
|
-> ResponseHeaders -- Headers
|
||||||
-> ByteString -- Content-Type header
|
-> ByteString -- Content-Type header
|
||||||
-> ByteString -- Request body
|
-> ByteString -- Request body
|
||||||
-> Maybe (Either String a)
|
-> Maybe (Either String a)
|
||||||
|
|
||||||
instance ( AllMimeUnrender ctyps a, IsNonEmpty ctyps
|
instance ( AllMimeUnrender ctyps a, IsNonEmpty ctyps
|
||||||
) => AllCTUnrender ctyps a where
|
) => AllCTUnrender ctyps a where
|
||||||
handleCTypeH _ ctypeH body = M.mapContentMedia lkup (cs ctypeH)
|
handleCTypeH _ hs ctypeH body = M.mapContentMedia lkup (cs ctypeH)
|
||||||
where lkup = allMimeUnrender (Proxy :: Proxy ctyps) body
|
where lkup = allMimeUnrender (Proxy :: Proxy ctyps) hs body
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
-- * Utils (Internal)
|
-- * Utils (Internal)
|
||||||
|
@ -211,7 +214,7 @@ instance ( AllMimeUnrender ctyps a, IsNonEmpty ctyps
|
||||||
class AllMimeRender (list :: [*]) a where
|
class AllMimeRender (list :: [*]) a where
|
||||||
allMimeRender :: Proxy list
|
allMimeRender :: Proxy list
|
||||||
-> a -- value to serialize
|
-> a -- value to serialize
|
||||||
-> [(M.MediaType, ByteString)] -- content-types/response pairs
|
-> [(M.MediaType, (ResponseHeaders, ByteString))] -- content-types/response pairs
|
||||||
|
|
||||||
instance ( MimeRender ctyp a ) => AllMimeRender '[ctyp] a where
|
instance ( MimeRender ctyp a ) => AllMimeRender '[ctyp] a where
|
||||||
allMimeRender _ a = [(contentType pctyp, toByteString pctyp a)]
|
allMimeRender _ a = [(contentType pctyp, toByteString pctyp a)]
|
||||||
|
@ -234,17 +237,18 @@ instance AllMimeRender '[] a where
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
class AllMimeUnrender (list :: [*]) a where
|
class AllMimeUnrender (list :: [*]) a where
|
||||||
allMimeUnrender :: Proxy list
|
allMimeUnrender :: Proxy list
|
||||||
|
-> ResponseHeaders
|
||||||
-> ByteString
|
-> ByteString
|
||||||
-> [(M.MediaType, Either String a)]
|
-> [(M.MediaType, Either String a)]
|
||||||
|
|
||||||
instance AllMimeUnrender '[] a where
|
instance AllMimeUnrender '[] a where
|
||||||
allMimeUnrender _ _ = []
|
allMimeUnrender _ _ _ = []
|
||||||
|
|
||||||
instance ( MimeUnrender ctyp a
|
instance ( MimeUnrender ctyp a
|
||||||
, AllMimeUnrender ctyps a
|
, AllMimeUnrender ctyps a
|
||||||
) => AllMimeUnrender (ctyp ': ctyps) a where
|
) => AllMimeUnrender (ctyp ': ctyps) a where
|
||||||
allMimeUnrender _ val = (contentType pctyp, fromByteString pctyp val)
|
allMimeUnrender _ hs val = (contentType pctyp, fromByteString pctyp hs val)
|
||||||
:(allMimeUnrender pctyps val)
|
:(allMimeUnrender pctyps hs val)
|
||||||
where pctyp = Proxy :: Proxy ctyp
|
where pctyp = Proxy :: Proxy ctyp
|
||||||
pctyps = Proxy :: Proxy ctyps
|
pctyps = Proxy :: Proxy ctyps
|
||||||
|
|
||||||
|
@ -257,29 +261,29 @@ type family IsNonEmpty (list :: [*]) :: Constraint where
|
||||||
|
|
||||||
-- | `encode`
|
-- | `encode`
|
||||||
instance ToJSON a => MimeRender JSON a where
|
instance ToJSON a => MimeRender JSON a where
|
||||||
toByteString _ = encode
|
toByteString _ = ([],) . encode
|
||||||
|
|
||||||
-- | @encodeFormUrlEncoded . toFormUrlEncoded@
|
-- | @encodeFormUrlEncoded . toFormUrlEncoded@
|
||||||
-- Note that the @fromByteString p (toByteString p x) == Right x@ law only
|
-- Note that the @fromByteString p (toByteString p x) == Right x@ law only
|
||||||
-- holds if every element of x is non-null (i.e., not @("", "")@)
|
-- holds if every element of x is non-null (i.e., not @("", "")@)
|
||||||
instance ToFormUrlEncoded a => MimeRender FormUrlEncoded a where
|
instance ToFormUrlEncoded a => MimeRender FormUrlEncoded a where
|
||||||
toByteString _ = encodeFormUrlEncoded . toFormUrlEncoded
|
toByteString _ = ([],) . encodeFormUrlEncoded . toFormUrlEncoded
|
||||||
|
|
||||||
-- | `TextL.encodeUtf8`
|
-- | `TextL.encodeUtf8`
|
||||||
instance MimeRender PlainText TextL.Text where
|
instance MimeRender PlainText TextL.Text where
|
||||||
toByteString _ = TextL.encodeUtf8
|
toByteString _ = ([],) . TextL.encodeUtf8
|
||||||
|
|
||||||
-- | @fromStrict . TextS.encodeUtf8@
|
-- | @fromStrict . TextS.encodeUtf8@
|
||||||
instance MimeRender PlainText TextS.Text where
|
instance MimeRender PlainText TextS.Text where
|
||||||
toByteString _ = fromStrict . TextS.encodeUtf8
|
toByteString _ = ([],) . fromStrict . TextS.encodeUtf8
|
||||||
|
|
||||||
-- | @id@
|
-- | @id@
|
||||||
instance MimeRender OctetStream ByteString where
|
instance MimeRender OctetStream ByteString where
|
||||||
toByteString _ = id
|
toByteString _ = ([],)
|
||||||
|
|
||||||
-- | `fromStrict`
|
-- | `fromStrict`
|
||||||
instance MimeRender OctetStream BS.ByteString where
|
instance MimeRender OctetStream BS.ByteString where
|
||||||
toByteString _ = fromStrict
|
toByteString _ = ([],) . fromStrict
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
@ -294,29 +298,29 @@ eitherDecodeLenient input = do
|
||||||
|
|
||||||
-- | `eitherDecode`
|
-- | `eitherDecode`
|
||||||
instance FromJSON a => MimeUnrender JSON a where
|
instance FromJSON a => MimeUnrender JSON a where
|
||||||
fromByteString _ = eitherDecodeLenient
|
fromByteString _ _ = eitherDecodeLenient
|
||||||
|
|
||||||
-- | @decodeFormUrlEncoded >=> fromFormUrlEncoded@
|
-- | @decodeFormUrlEncoded >=> fromFormUrlEncoded@
|
||||||
-- Note that the @fromByteString p (toByteString p x) == Right x@ law only
|
-- Note that the @fromByteString p (toByteString p x) == Right x@ law only
|
||||||
-- holds if every element of x is non-null (i.e., not @("", "")@)
|
-- holds if every element of x is non-null (i.e., not @("", "")@)
|
||||||
instance FromFormUrlEncoded a => MimeUnrender FormUrlEncoded a where
|
instance FromFormUrlEncoded a => MimeUnrender FormUrlEncoded a where
|
||||||
fromByteString _ = decodeFormUrlEncoded >=> fromFormUrlEncoded
|
fromByteString _ _ = decodeFormUrlEncoded >=> fromFormUrlEncoded
|
||||||
|
|
||||||
-- | @left show . TextL.decodeUtf8'@
|
-- | @left show . TextL.decodeUtf8'@
|
||||||
instance MimeUnrender PlainText TextL.Text where
|
instance MimeUnrender PlainText TextL.Text where
|
||||||
fromByteString _ = left show . TextL.decodeUtf8'
|
fromByteString _ _ = left show . TextL.decodeUtf8'
|
||||||
|
|
||||||
-- | @left show . TextS.decodeUtf8' . toStrict@
|
-- | @left show . TextS.decodeUtf8' . toStrict@
|
||||||
instance MimeUnrender PlainText TextS.Text where
|
instance MimeUnrender PlainText TextS.Text where
|
||||||
fromByteString _ = left show . TextS.decodeUtf8' . toStrict
|
fromByteString _ _ = left show . TextS.decodeUtf8' . toStrict
|
||||||
|
|
||||||
-- | @Right . id@
|
-- | @Right . id@
|
||||||
instance MimeUnrender OctetStream ByteString where
|
instance MimeUnrender OctetStream ByteString where
|
||||||
fromByteString _ = Right . id
|
fromByteString _ _ = Right
|
||||||
|
|
||||||
-- | @Right . toStrict@
|
-- | @Right . toStrict@
|
||||||
instance MimeUnrender OctetStream BS.ByteString where
|
instance MimeUnrender OctetStream BS.ByteString where
|
||||||
fromByteString _ = Right . toStrict
|
fromByteString _ _ = Right . toStrict
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
{-# LANGUAGE DeriveGeneric #-}
|
{-# LANGUAGE DeriveGeneric #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE TupleSections #-}
|
||||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
module Servant.API.ContentTypesSpec where
|
module Servant.API.ContentTypesSpec where
|
||||||
|
|
||||||
|
@ -36,11 +37,11 @@ spec = describe "Servant.API.ContentTypes" $ do
|
||||||
|
|
||||||
it "has fromByteString reverse toByteString for valid top-level json ([Int]) " $ do
|
it "has fromByteString reverse toByteString for valid top-level json ([Int]) " $ do
|
||||||
let p = Proxy :: Proxy JSON
|
let p = Proxy :: Proxy JSON
|
||||||
property $ \x -> fromByteString p (toByteString p x) == Right (x::[Int])
|
property $ \x -> uncurry (fromByteString p) (toByteString p x) == Right (x::[Int])
|
||||||
|
|
||||||
it "has fromByteString reverse toByteString for valid top-level json " $ do
|
it "has fromByteString reverse toByteString for valid top-level json " $ do
|
||||||
let p = Proxy :: Proxy JSON
|
let p = Proxy :: Proxy JSON
|
||||||
property $ \x -> fromByteString p (toByteString p x) == Right (x::SomeData)
|
property $ \x -> uncurry (fromByteString p) (toByteString p x) == Right (x::SomeData)
|
||||||
|
|
||||||
describe "The FormUrlEncoded Content-Type type" $ do
|
describe "The FormUrlEncoded Content-Type type" $ do
|
||||||
|
|
||||||
|
@ -50,39 +51,39 @@ spec = describe "Servant.API.ContentTypes" $ do
|
||||||
it "has fromByteString reverse toByteString" $ do
|
it "has fromByteString reverse toByteString" $ do
|
||||||
let p = Proxy :: Proxy FormUrlEncoded
|
let p = Proxy :: Proxy FormUrlEncoded
|
||||||
property $ \x -> all isNonNull x
|
property $ \x -> all isNonNull x
|
||||||
==> fromByteString p (toByteString p x) == Right (x::[(TextS.Text,TextS.Text)])
|
==> uncurry (fromByteString p) (toByteString p x) == Right (x::[(TextS.Text,TextS.Text)])
|
||||||
|
|
||||||
it "has fromByteString reverse exportParams (Network.URL)" $ do
|
it "has fromByteString reverse exportParams (Network.URL)" $ do
|
||||||
let p = Proxy :: Proxy FormUrlEncoded
|
let p = Proxy :: Proxy FormUrlEncoded
|
||||||
property $ \x -> all isNonNull x
|
property $ \x -> all isNonNull x
|
||||||
==> (fromByteString p . cs . exportParams . map (cs *** cs) $ x) == Right (x::[(TextS.Text,TextS.Text)])
|
==> (fromByteString p [] . cs . exportParams . map (cs *** cs) $ x) == Right (x::[(TextS.Text,TextS.Text)])
|
||||||
|
|
||||||
it "has importParams (Network.URL) reverse toByteString" $ do
|
it "has importParams (Network.URL) reverse toByteString" $ do
|
||||||
let p = Proxy :: Proxy FormUrlEncoded
|
let p = Proxy :: Proxy FormUrlEncoded
|
||||||
property $ \x -> all isNonNull x
|
property $ \x -> all isNonNull x
|
||||||
==> (fmap (map (cs *** cs)) . importParams . cs . toByteString p $ x) == Just (x::[(TextS.Text,TextS.Text)])
|
==> (fmap (map (cs *** cs)) . importParams . cs . snd . toByteString p $ x) == Just (x::[(TextS.Text,TextS.Text)])
|
||||||
|
|
||||||
describe "The PlainText Content-Type type" $ do
|
describe "The PlainText Content-Type type" $ do
|
||||||
|
|
||||||
it "has fromByteString reverse toByteString (lazy Text)" $ do
|
it "has fromByteString reverse toByteString (lazy Text)" $ do
|
||||||
let p = Proxy :: Proxy PlainText
|
let p = Proxy :: Proxy PlainText
|
||||||
property $ \x -> fromByteString p (toByteString p x) == Right (x::TextL.Text)
|
property $ \x -> uncurry (fromByteString p) (toByteString p x) == Right (x::TextL.Text)
|
||||||
|
|
||||||
it "has fromByteString reverse toByteString (strict Text)" $ do
|
it "has fromByteString reverse toByteString (strict Text)" $ do
|
||||||
let p = Proxy :: Proxy PlainText
|
let p = Proxy :: Proxy PlainText
|
||||||
property $ \x -> fromByteString p (toByteString p x) == Right (x::TextS.Text)
|
property $ \x -> uncurry (fromByteString p) (toByteString p x) == Right (x::TextS.Text)
|
||||||
|
|
||||||
describe "The OctetStream Content-Type type" $ do
|
describe "The OctetStream Content-Type type" $ do
|
||||||
|
|
||||||
it "is id (Lazy ByteString)" $ do
|
it "is id (Lazy ByteString)" $ do
|
||||||
let p = Proxy :: Proxy OctetStream
|
let p = Proxy :: Proxy OctetStream
|
||||||
property $ \x -> toByteString p x == (x :: BSL.ByteString)
|
property $ \x -> toByteString p x == ([], x :: BSL.ByteString)
|
||||||
&& fromByteString p x == Right x
|
&& fromByteString p [] x == Right x
|
||||||
|
|
||||||
it "is fromStrict/toStrict (Strict ByteString)" $ do
|
it "is fromStrict/toStrict (Strict ByteString)" $ do
|
||||||
let p = Proxy :: Proxy OctetStream
|
let p = Proxy :: Proxy OctetStream
|
||||||
property $ \x -> toByteString p x == BSL.fromStrict (x :: ByteString)
|
property $ \x -> toByteString p x == ([], BSL.fromStrict x)
|
||||||
&& fromByteString p (BSL.fromStrict x) == Right x
|
&& fromByteString p [] (BSL.fromStrict x) == Right x
|
||||||
|
|
||||||
describe "handleAcceptH" $ do
|
describe "handleAcceptH" $ do
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ spec = describe "Servant.API.ContentTypes" $ do
|
||||||
|
|
||||||
it "returns the appropriately serialized representation" $ do
|
it "returns the appropriately serialized representation" $ do
|
||||||
property $ \x -> handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (x :: SomeData)
|
property $ \x -> handleAcceptH (Proxy :: Proxy '[JSON]) "*/*" (x :: SomeData)
|
||||||
== Just ("application/json", encode x)
|
== Just ("application/json", ([], encode x))
|
||||||
|
|
||||||
it "respects the Accept spec ordering" $ do
|
it "respects the Accept spec ordering" $ do
|
||||||
let highest a b c = maximumBy (compare `on` snd)
|
let highest a b c = maximumBy (compare `on` snd)
|
||||||
|
@ -128,17 +129,17 @@ spec = describe "Servant.API.ContentTypes" $ do
|
||||||
describe "handleCTypeH" $ do
|
describe "handleCTypeH" $ do
|
||||||
|
|
||||||
it "returns Nothing if the 'Content-Type' header doesn't match" $ do
|
it "returns Nothing if the 'Content-Type' header doesn't match" $ do
|
||||||
handleCTypeH (Proxy :: Proxy '[JSON]) "text/plain" "𝓽𝓱𝓮 𝓽𝓲𝓶𝓮 𝓱𝓪𝓼 𝓬𝓸𝓶𝓮, 𝓽𝓱𝓮 𝔀𝓪𝓵𝓻𝓾𝓼 𝓼𝓪𝓲𝓭 "
|
handleCTypeH (Proxy :: Proxy '[JSON]) [] "text/plain" "𝓽𝓱𝓮 𝓽𝓲𝓶𝓮 𝓱𝓪𝓼 𝓬𝓸𝓶𝓮, 𝓽𝓱𝓮 𝔀𝓪𝓵𝓻𝓾𝓼 𝓼𝓪𝓲𝓭 "
|
||||||
`shouldBe` (Nothing :: Maybe (Either String Value))
|
`shouldBe` (Nothing :: Maybe (Either String Value))
|
||||||
|
|
||||||
context "the 'Content-Type' header matches" $ do
|
context "the 'Content-Type' header matches" $ do
|
||||||
it "returns Just if the parameter matches" $ do
|
it "returns Just if the parameter matches" $ do
|
||||||
handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
|
handleCTypeH (Proxy :: Proxy '[JSON]) [] "application/json"
|
||||||
"𝕥𝕠 𝕥𝕒𝕝𝕜 𝕠𝕗 𝕞𝕒𝕟𝕪 𝕥𝕙𝕚𝕟𝕘𝕤 "
|
"𝕥𝕠 𝕥𝕒𝕝𝕜 𝕠𝕗 𝕞𝕒𝕟𝕪 𝕥𝕙𝕚𝕟𝕘𝕤 "
|
||||||
`shouldSatisfy` (isJust :: Maybe (Either String Value) -> Bool)
|
`shouldSatisfy` (isJust :: Maybe (Either String Value) -> Bool)
|
||||||
|
|
||||||
it "returns Just if there is no parameter" $ do
|
it "returns Just if there is no parameter" $ do
|
||||||
handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
|
handleCTypeH (Proxy :: Proxy '[JSON]) [] "application/json"
|
||||||
"𝕥𝕠 𝕥𝕒𝕝𝕜 𝕠𝕗 𝕞𝕒𝕟𝕪 𝕥𝕙𝕚𝕟𝕘𝕤 "
|
"𝕥𝕠 𝕥𝕒𝕝𝕜 𝕠𝕗 𝕞𝕒𝕟𝕪 𝕥𝕙𝕚𝕟𝕘𝕤 "
|
||||||
`shouldSatisfy` (isJust :: Maybe (Either String Value) -> Bool)
|
`shouldSatisfy` (isJust :: Maybe (Either String Value) -> Bool)
|
||||||
|
|
||||||
|
@ -146,13 +147,13 @@ spec = describe "Servant.API.ContentTypes" $ do
|
||||||
let isJustLeft :: Maybe (Either String Value) -> Bool
|
let isJustLeft :: Maybe (Either String Value) -> Bool
|
||||||
isJustLeft (Just (Left _)) = True
|
isJustLeft (Just (Left _)) = True
|
||||||
isJustLeft _ = False
|
isJustLeft _ = False
|
||||||
handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
|
handleCTypeH (Proxy :: Proxy '[JSON]) [] "application/json"
|
||||||
"𝕺𝖋 𝖘𝖍𝖔𝖊𝖘--𝖆𝖓𝖉 𝖘𝖍𝖎𝖕𝖘--𝖆𝖓𝖉 𝖘𝖊𝖆𝖑𝖎𝖓𝖌-𝖜𝖆𝖝-- "
|
"𝕺𝖋 𝖘𝖍𝖔𝖊𝖘--𝖆𝖓𝖉 𝖘𝖍𝖎𝖕𝖘--𝖆𝖓𝖉 𝖘𝖊𝖆𝖑𝖎𝖓𝖌-𝖜𝖆𝖝-- "
|
||||||
`shouldSatisfy` isJustLeft
|
`shouldSatisfy` isJustLeft
|
||||||
|
|
||||||
it "returns Just (Right val) if the decoding succeeds" $ do
|
it "returns Just (Right val) if the decoding succeeds" $ do
|
||||||
let val = SomeData "Of cabbages--and kings" 12
|
let val = SomeData "Of cabbages--and kings" 12
|
||||||
handleCTypeH (Proxy :: Proxy '[JSON]) "application/json"
|
handleCTypeH (Proxy :: Proxy '[JSON]) [] "application/json"
|
||||||
(encode val)
|
(encode val)
|
||||||
`shouldBe` Just (Right val)
|
`shouldBe` Just (Right val)
|
||||||
|
|
||||||
|
@ -182,13 +183,13 @@ instance Arbitrary ZeroToOne where
|
||||||
arbitrary = ZeroToOne <$> elements [ x / 10 | x <- [1..10]]
|
arbitrary = ZeroToOne <$> elements [ x / 10 | x <- [1..10]]
|
||||||
|
|
||||||
instance MimeRender OctetStream Int where
|
instance MimeRender OctetStream Int where
|
||||||
toByteString _ = cs . show
|
toByteString _ = ([],) . cs . show
|
||||||
|
|
||||||
instance MimeRender PlainText Int where
|
instance MimeRender PlainText Int where
|
||||||
toByteString _ = cs . show
|
toByteString _ = ([],) . cs . show
|
||||||
|
|
||||||
instance MimeRender PlainText ByteString where
|
instance MimeRender PlainText ByteString where
|
||||||
toByteString _ = cs
|
toByteString _ = ([],) . cs
|
||||||
|
|
||||||
instance ToJSON ByteString where
|
instance ToJSON ByteString where
|
||||||
toJSON x = object [ "val" .= x ]
|
toJSON x = object [ "val" .= x ]
|
||||||
|
|
Loading…
Reference in a new issue