Drop Mime{,Un}Render instances that do not shrink head.

This commit is contained in:
Matthias Fischmann 2020-12-06 15:31:43 +01:00
parent 49801db151
commit f95d2fcadc
No known key found for this signature in database
GPG key ID: 0DE4AA9C5446EBF4
11 changed files with 67 additions and 29 deletions

View file

@ -30,6 +30,9 @@ instance ToJSON Greet
instance MimeRender PlainText Greet where instance MimeRender PlainText Greet where
mimeRender Proxy (Greet s) = "\"" <> cs s <> "\"" mimeRender Proxy (Greet s) = "\"" <> cs s <> "\""
instance MimeRender JSON Greet where
mimeRender Proxy = encode
-- We add some useful annotations to our captures, -- We add some useful annotations to our captures,
-- query parameters and request body to make the docs -- query parameters and request body to make the docs
-- really helpful. -- really helpful.

View file

@ -216,3 +216,6 @@ compareWith f msg x y = unless (f x y) $ assertFailure $
golden :: TestName -> FilePath -> String -> TestTreeM () golden :: TestName -> FilePath -> String -> TestTreeM ()
golden n fp contents = TestTreeM $ tell golden n fp contents = TestTreeM $ tell
[ goldenVsString n fp (return (cs contents)) ] [ goldenVsString n fp (return (cs contents)) ]
instance ToJSON a => MimeRender JSON a where
mimeRender _ = encode

View file

@ -1,5 +1,7 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PolyKinds #-} {-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilies #-}
@ -26,6 +28,8 @@ newtype Greet = Greet { _msg :: Text }
instance FromJSON Greet instance FromJSON Greet
instance ToJSON Greet instance ToJSON Greet
instance ToJSON a => MimeRender JSON a where mimeRender _ = encode
-- API specification -- API specification
type TestApi = type TestApi =
-- GET /hello/:name?capital={true, false} returns a Greet as JSON -- GET /hello/:name?capital={true, false} returns a Greet as JSON

View file

@ -1,9 +1,14 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Servant.ArbitraryMonadServerSpec where module Servant.ArbitraryMonadServerSpec where
import Control.Monad.Reader import Control.Monad.Reader
import Data.Aeson
(encode)
import Data.Functor.Identity import Data.Functor.Identity
import Data.Proxy import Data.Proxy
import Servant.API import Servant.API
@ -60,3 +65,7 @@ enterSpec = describe "Enter" $ do
with (return (serve combinedAPI combinedReaderServer)) $ do with (return (serve combinedAPI combinedReaderServer)) $ do
it "allows combnation of enters" $ do it "allows combnation of enters" $ do
get "bool" `shouldRespondWith` "true" get "bool" `shouldRespondWith` "true"
instance MimeRender JSON Bool where mimeRender _ = encode
instance MimeRender JSON Int where mimeRender _ = encode
instance MimeRender JSON String where mimeRender _ = encode

View file

@ -1,7 +1,13 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Servant.HoistSpec where module Servant.HoistSpec where
import Data.Aeson
(ToJSON, encode)
import Test.Hspec import Test.Hspec
(Spec) (Spec)
@ -31,6 +37,8 @@ f = id
server' :: App Int :<|> (String -> App Bool) server' :: App Int :<|> (String -> App Bool)
server' = hoistServer api f server server' = hoistServer api f server
instance ToJSON a => MimeRender JSON a where mimeRender _ = encode
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Spec -- Spec
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View file

@ -360,4 +360,7 @@ instance MimeUnrender PlainText Int where
instance MimeRender PlainText Int where instance MimeRender PlainText Int where
mimeRender _ = BCL.pack . show mimeRender _ = BCL.pack . show
instance MimeRender JSON Integer where mimeRender _ = encode
instance MimeRender JSON Int where mimeRender _ = encode
-- }}} -- }}}

View file

@ -1,10 +1,14 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Servant.Server.UsingContextSpec where module Servant.Server.UsingContextSpec where
import Data.Aeson
(encode)
import Network.Wai import Network.Wai
import Test.Hspec import Test.Hspec
(Spec, describe, it) (Spec, describe, it)
@ -20,6 +24,8 @@ spec = do
spec3 spec3
spec4 spec4
instance MimeRender JSON String where mimeRender _ = encode
-- * API -- * API
type OneEntryAPI = type OneEntryAPI =

View file

@ -1,5 +1,6 @@
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
@ -50,6 +51,7 @@ import Servant.API
BasicAuthData (BasicAuthData), Capture, Capture', CaptureAll, BasicAuthData (BasicAuthData), Capture, Capture', CaptureAll,
Delete, EmptyAPI, Fragment, Get, HasStatus (StatusOf), Header, Delete, EmptyAPI, Fragment, Get, HasStatus (StatusOf), Header,
Headers, HttpVersion, IsSecure (..), JSON, Lenient, Headers, HttpVersion, IsSecure (..), JSON, Lenient,
MimeRender (..),
NoContent (..), NoContentVerb, NoFraming, OctetStream, Patch, NoContent (..), NoContentVerb, NoFraming, OctetStream, Patch,
PlainText, Post, Put, QueryFlag, QueryParam, QueryParams, Raw, PlainText, Post, Put, QueryFlag, QueryParam, QueryParams, Raw,
RemoteHost, ReqBody, SourceIO, StdMethod (..), Stream, Strict, RemoteHost, ReqBody, SourceIO, StdMethod (..), Stream, Strict,
@ -106,6 +108,8 @@ spec = do
-- * verbSpec {{{ -- * verbSpec {{{
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
instance {-# OVERLAPPABLE #-} ToJSON a => MimeRender JSON a where mimeRender _ = encode
type VerbApi method status type VerbApi method status
= Verb method status '[JSON] Person = Verb method status '[JSON] Person
:<|> "noContent" :> NoContentVerb method :<|> "noContent" :> NoContentVerb method

View file

@ -154,6 +154,7 @@ test-suite spec
, base-compat , base-compat
, aeson , aeson
, bytestring , bytestring
, http-api-data
, http-media , http-media
, mtl , mtl
, servant , servant

View file

@ -74,7 +74,7 @@ import Control.Monad.Compat
import Control.DeepSeq import Control.DeepSeq
(NFData) (NFData)
import Data.Aeson import Data.Aeson
(FromJSON (..), ToJSON (..), encode) (FromJSON (..))
import Data.Aeson.Parser import Data.Aeson.Parser
(value) (value)
import Data.Aeson.Types import Data.Aeson.Types
@ -102,7 +102,7 @@ import qualified Network.HTTP.Media as M
import Prelude () import Prelude ()
import Prelude.Compat import Prelude.Compat
import Web.FormUrlEncoded import Web.FormUrlEncoded
(FromForm, ToForm, urlDecodeAsForm, urlEncodeAsForm) (FromForm, urlDecodeAsForm)
-- * Provided content types -- * Provided content types
data JSON deriving Typeable data JSON deriving Typeable
@ -327,18 +327,6 @@ instance ( MimeUnrender ctyp a
-------------------------------------------------------------------------- --------------------------------------------------------------------------
-- * MimeRender Instances -- * MimeRender Instances
-- | `encode`
instance {-# OVERLAPPABLE #-}
ToJSON a => MimeRender JSON a where
mimeRender _ = encode
-- | @urlEncodeAsForm@
-- Note that the @mimeUnrender p (mimeRender p x) == Right x@ law only
-- holds if every element of x is non-null (i.e., not @("", "")@)
instance {-# OVERLAPPABLE #-}
ToForm a => MimeRender FormUrlEncoded a where
mimeRender _ = urlEncodeAsForm
-- | `TextL.encodeUtf8` -- | `TextL.encodeUtf8`
instance MimeRender PlainText TextL.Text where instance MimeRender PlainText TextL.Text where
mimeRender _ = TextL.encodeUtf8 mimeRender _ = TextL.encodeUtf8
@ -388,16 +376,6 @@ eitherDecodeLenient input =
<* skipSpace <* skipSpace
<* (endOfInput <?> "trailing junk after valid JSON") <* (endOfInput <?> "trailing junk after valid JSON")
-- | `eitherDecode`
instance FromJSON a => MimeUnrender JSON a where
mimeUnrender _ = eitherDecodeLenient
-- | @urlDecodeAsForm@
-- Note that the @mimeUnrender p (mimeRender p x) == Right x@ law only
-- holds if every element of x is non-null (i.e., not @("", "")@)
instance FromForm a => MimeUnrender FormUrlEncoded a where
mimeUnrender _ = left TextS.unpack . urlDecodeAsForm
-- | @left show . TextL.decodeUtf8'@ -- | @left show . TextL.decodeUtf8'@
instance MimeUnrender PlainText TextL.Text where instance MimeUnrender PlainText TextL.Text where
mimeUnrender _ = left show . TextL.decodeUtf8' mimeUnrender _ = left show . TextL.decodeUtf8'

View file

@ -1,6 +1,7 @@
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-} {-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PackageImports #-} {-# LANGUAGE PackageImports #-}
@ -39,6 +40,8 @@ import Test.QuickCheck
import "quickcheck-instances" Test.QuickCheck.Instances () import "quickcheck-instances" Test.QuickCheck.Instances ()
import Text.Read import Text.Read
(readMaybe) (readMaybe)
import Web.FormUrlEncoded
(ToForm, urlEncodeAsForm)
import Servant.API.ContentTypes import Servant.API.ContentTypes
@ -271,3 +274,19 @@ addToAccept p (ZeroToOne f) (AcceptHeader h) = AcceptHeader (cont h)
where new = cs (show $ contentType p) `append` "; q=" `append` pack (show f) where new = cs (show $ contentType p) `append` "; q=" `append` pack (show f)
cont "" = new cont "" = new
cont old = old `append` ", " `append` new cont old = old `append` ", " `append` new
-- | `encode`
--
-- This instance is not provided with the library to avoid unsolvable ambiguous instance
-- problems. Example: @instance MimeRender a => MimeRender (WithStatus n a)@
instance {-# OVERLAPPABLE #-} ToJSON a => MimeRender JSON a where
mimeRender _ = encode
-- | @urlEncodeAsForm@
-- Note that the @mimeUnrender p (mimeRender p x) == Right x@ law only
-- holds if every element of x is non-null (i.e., not @("", "")@)
--
-- This instance is not provided with the library to avoid unsolvable ambiguous instance
-- problems.
instance {-# OVERLAPPABLE #-} ToForm a => MimeRender FormUrlEncoded a where
mimeRender _ = urlEncodeAsForm