From 50b05860b760bb2897377fa967947074f50ed3da Mon Sep 17 00:00:00 2001 From: "Julian K. Arni" Date: Sun, 3 May 2015 01:45:17 +0200 Subject: [PATCH] Remove Canonicalize --- servant-client/CHANGELOG.md | 1 - servant-client/src/Servant/Client.hs | 79 +++++++++---------- servant-client/test/Servant/ClientSpec.hs | 4 +- servant-docs/CHANGELOG.md | 1 - servant-docs/src/Servant/Docs/Internal.hs | 12 +-- servant-jquery/src/Servant/JQuery.hs | 7 +- servant-jquery/src/Servant/JQuery/Internal.hs | 38 +++++---- servant-server/CHANGELOG.md | 1 - servant-server/src/Servant/Server.hs | 6 +- servant-server/src/Servant/Server/Internal.hs | 78 +++++++++--------- servant/CHANGELOG.md | 1 - servant/src/Servant/API.hs | 34 -------- 12 files changed, 106 insertions(+), 156 deletions(-) diff --git a/servant-client/CHANGELOG.md b/servant-client/CHANGELOG.md index 166e0f9d..814e20f9 100644 --- a/servant-client/CHANGELOG.md +++ b/servant-client/CHANGELOG.md @@ -7,7 +7,6 @@ * Make the clients for `Raw` endpoints return the whole `Response` value (to be able to access response headers for example) * Support for PATCH * Make () instances expect No Content status code, and not try to decode body. -* `Canonicalize` API types before generating client functions for them * Add support for response headers 0.2.2 diff --git a/servant-client/src/Servant/Client.hs b/servant-client/src/Servant/Client.hs index 39fe3f55..e09b138d 100644 --- a/servant-client/src/Servant/Client.hs +++ b/servant-client/src/Servant/Client.hs @@ -53,17 +53,16 @@ import Servant.Common.Req -- > getAllBooks :: BaseUrl -> EitherT String IO [Book] -- > postNewBook :: Book -> BaseUrl -> EitherT String IO Book -- > (getAllBooks :<|> postNewBook) = client myApi -client :: HasClient (Canonicalize layout) => Proxy layout -> Client layout -client p = clientWithRoute (canonicalize p) defReq +client :: HasClient layout => Proxy layout -> Client layout +client p = clientWithRoute p defReq -- | This class lets us define how each API combinator -- influences the creation of an HTTP request. It's mostly -- an internal class, you can just use 'client'. class HasClient layout where - type Client' layout :: * - clientWithRoute :: Proxy layout -> Req -> Client' layout + type Client layout :: * + clientWithRoute :: Proxy layout -> Req -> Client layout -type Client layout = Client' (Canonicalize layout) -- | A client querying function for @a ':<|>' b@ will actually hand you -- one function for querying @a@ and another one for querying @b@, @@ -79,7 +78,7 @@ type Client layout = Client' (Canonicalize layout) -- > postNewBook :: Book -> BaseUrl -> EitherT String IO Book -- > (getAllBooks :<|> postNewBook) = client myApi instance (HasClient a, HasClient b) => HasClient (a :<|> b) where - type Client' (a :<|> b) = Client' a :<|> Client' b + type Client (a :<|> b) = Client a :<|> Client b clientWithRoute Proxy req = clientWithRoute (Proxy :: Proxy a) req :<|> clientWithRoute (Proxy :: Proxy b) req @@ -106,8 +105,8 @@ instance (HasClient a, HasClient b) => HasClient (a :<|> b) where instance (KnownSymbol capture, ToText a, HasClient sublayout) => HasClient (Capture capture a :> sublayout) where - type Client' (Capture capture a :> sublayout) = - a -> Client' sublayout + type Client (Capture capture a :> sublayout) = + a -> Client sublayout clientWithRoute Proxy req val = clientWithRoute (Proxy :: Proxy sublayout) $ @@ -120,7 +119,7 @@ instance (KnownSymbol capture, ToText a, HasClient sublayout) -- will just require an argument that specifies the scheme, host -- and port to send the request to. instance HasClient Delete where - type Client' Delete = BaseUrl -> EitherT ServantError IO () + type Client Delete = BaseUrl -> EitherT ServantError IO () clientWithRoute Proxy req host = void $ performRequest H.methodDelete req (`elem` [200, 202, 204]) host @@ -134,7 +133,7 @@ instance {-# OVERLAPPABLE #-} #endif (MimeUnrender ct result) => HasClient (Get (ct ': cts) result) where - type Client' (Get (ct ': cts) result) = BaseUrl -> EitherT ServantError IO result + type Client (Get (ct ': cts) result) = BaseUrl -> EitherT ServantError IO result clientWithRoute Proxy req host = snd <$> performRequestCT (Proxy :: Proxy ct) H.methodGet req [200, 203] host @@ -145,7 +144,7 @@ instance {-# OVERLAPPING #-} #endif HasClient (Get (ct ': cts) ()) where - type Client' (Get (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () + type Client (Get (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () clientWithRoute Proxy req host = performRequestNoBody H.methodGet req [204] host @@ -157,7 +156,7 @@ instance #endif ( MimeUnrender ct a, BuildHeadersTo ls ) => HasClient (Get (ct ': cts) (Headers ls a)) where - type Client' (Get (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) + type Client (Get (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) clientWithRoute Proxy req host = do (hdrs, resp) <- performRequestCT (Proxy :: Proxy ct) H.methodGet req [200, 203, 204] host return $ Headers { getResponse = resp @@ -192,8 +191,8 @@ instance instance (KnownSymbol sym, ToText a, HasClient sublayout) => HasClient (Header sym a :> sublayout) where - type Client' (Header sym a :> sublayout) = - Maybe a -> Client' sublayout + type Client (Header sym a :> sublayout) = + Maybe a -> Client sublayout clientWithRoute Proxy req mval = clientWithRoute (Proxy :: Proxy sublayout) $ @@ -210,7 +209,7 @@ instance {-# OVERLAPPABLE #-} #endif (MimeUnrender ct a) => HasClient (Post (ct ': cts) a) where - type Client' (Post (ct ': cts) a) = BaseUrl -> EitherT ServantError IO a + type Client (Post (ct ': cts) a) = BaseUrl -> EitherT ServantError IO a clientWithRoute Proxy req uri = snd <$> performRequestCT (Proxy :: Proxy ct) H.methodPost req [200,201] uri @@ -222,7 +221,7 @@ instance {-# OVERLAPPING #-} #endif HasClient (Post (ct ': cts) ()) where - type Client' (Post (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () + type Client (Post (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () clientWithRoute Proxy req host = void $ performRequestNoBody H.methodPost req [204] host @@ -234,7 +233,7 @@ instance #endif ( MimeUnrender ct a, BuildHeadersTo ls ) => HasClient (Post (ct ': cts) (Headers ls a)) where - type Client' (Post (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) + type Client (Post (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) clientWithRoute Proxy req host = do (hdrs, resp) <- performRequestCT (Proxy :: Proxy ct) H.methodPost req [200, 201] host return $ Headers { getResponse = resp @@ -250,7 +249,7 @@ instance {-# OVERLAPPABLE #-} #endif (MimeUnrender ct a) => HasClient (Put (ct ': cts) a) where - type Client' (Put (ct ': cts) a) = BaseUrl -> EitherT ServantError IO a + type Client (Put (ct ': cts) a) = BaseUrl -> EitherT ServantError IO a clientWithRoute Proxy req host = snd <$> performRequestCT (Proxy :: Proxy ct) H.methodPut req [200,201] host @@ -262,7 +261,7 @@ instance {-# OVERLAPPING #-} #endif HasClient (Put (ct ': cts) ()) where - type Client' (Put (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () + type Client (Put (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () clientWithRoute Proxy req host = void $ performRequestNoBody H.methodPut req [204] host @@ -274,7 +273,7 @@ instance #endif ( MimeUnrender ct a, BuildHeadersTo ls ) => HasClient (Put (ct ': cts) (Headers ls a)) where - type Client' (Put (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) + type Client (Put (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) clientWithRoute Proxy req host = do (hdrs, resp) <- performRequestCT (Proxy :: Proxy ct) H.methodPut req [200, 201] host return $ Headers { getResponse = resp @@ -290,7 +289,7 @@ instance {-# OVERLAPPABLE #-} #endif (MimeUnrender ct a) => HasClient (Patch (ct ': cts) a) where - type Client' (Patch (ct ': cts) a) = BaseUrl -> EitherT ServantError IO a + type Client (Patch (ct ': cts) a) = BaseUrl -> EitherT ServantError IO a clientWithRoute Proxy req host = snd <$> performRequestCT (Proxy :: Proxy ct) H.methodPatch req [200,201] host @@ -302,7 +301,7 @@ instance {-# OVERLAPPING #-} #endif HasClient (Patch (ct ': cts) ()) where - type Client' (Patch (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () + type Client (Patch (ct ': cts) ()) = BaseUrl -> EitherT ServantError IO () clientWithRoute Proxy req host = void $ performRequestNoBody H.methodPatch req [204] host @@ -314,7 +313,7 @@ instance #endif ( MimeUnrender ct a, BuildHeadersTo ls ) => HasClient (Patch (ct ': cts) (Headers ls a)) where - type Client' (Patch (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) + type Client (Patch (ct ': cts) (Headers ls a)) = BaseUrl -> EitherT ServantError IO (Headers ls a) clientWithRoute Proxy req host = do (hdrs, resp) <- performRequestCT (Proxy :: Proxy ct) H.methodPatch req [200, 201, 204] host return $ Headers { getResponse = resp @@ -349,8 +348,8 @@ instance instance (KnownSymbol sym, ToText a, HasClient sublayout) => HasClient (QueryParam sym a :> sublayout) where - type Client' (QueryParam sym a :> sublayout) = - Maybe a -> Client' sublayout + type Client (QueryParam sym a :> sublayout) = + Maybe a -> Client sublayout -- if mparam = Nothing, we don't add it to the query string clientWithRoute Proxy req mparam = @@ -391,8 +390,8 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout) instance (KnownSymbol sym, ToText a, HasClient sublayout) => HasClient (QueryParams sym a :> sublayout) where - type Client' (QueryParams sym a :> sublayout) = - [a] -> Client' sublayout + type Client (QueryParams sym a :> sublayout) = + [a] -> Client sublayout clientWithRoute Proxy req paramlist = clientWithRoute (Proxy :: Proxy sublayout) $ @@ -426,8 +425,8 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout) instance (KnownSymbol sym, HasClient sublayout) => HasClient (QueryFlag sym :> sublayout) where - type Client' (QueryFlag sym :> sublayout) = - Bool -> Client' sublayout + type Client (QueryFlag sym :> sublayout) = + Bool -> Client sublayout clientWithRoute Proxy req flag = clientWithRoute (Proxy :: Proxy sublayout) $ @@ -465,8 +464,8 @@ instance (KnownSymbol sym, HasClient sublayout) instance (KnownSymbol sym, ToText a, HasClient sublayout) => HasClient (MatrixParam sym a :> sublayout) where - type Client' (MatrixParam sym a :> sublayout) = - Maybe a -> Client' sublayout + type Client (MatrixParam sym a :> sublayout) = + Maybe a -> Client sublayout -- if mparam = Nothing, we don't add it to the query string clientWithRoute Proxy req mparam = @@ -506,8 +505,8 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout) instance (KnownSymbol sym, ToText a, HasClient sublayout) => HasClient (MatrixParams sym a :> sublayout) where - type Client' (MatrixParams sym a :> sublayout) = - [a] -> Client' sublayout + type Client (MatrixParams sym a :> sublayout) = + [a] -> Client sublayout clientWithRoute Proxy req paramlist = clientWithRoute (Proxy :: Proxy sublayout) $ @@ -541,8 +540,8 @@ instance (KnownSymbol sym, ToText a, HasClient sublayout) instance (KnownSymbol sym, HasClient sublayout) => HasClient (MatrixFlag sym :> sublayout) where - type Client' (MatrixFlag sym :> sublayout) = - Bool -> Client' sublayout + type Client (MatrixFlag sym :> sublayout) = + Bool -> Client sublayout clientWithRoute Proxy req flag = clientWithRoute (Proxy :: Proxy sublayout) $ @@ -555,9 +554,9 @@ instance (KnownSymbol sym, HasClient sublayout) -- | Pick a 'Method' and specify where the server you want to query is. You get -- back the full `Response`. instance HasClient Raw where - type Client' Raw = H.Method -> BaseUrl -> EitherT ServantError IO (Int, ByteString, MediaType, [HTTP.Header], Response ByteString) + type Client Raw = H.Method -> BaseUrl -> EitherT ServantError IO (Int, ByteString, MediaType, [HTTP.Header], Response ByteString) - clientWithRoute :: Proxy Raw -> Req -> Client' Raw + clientWithRoute :: Proxy Raw -> Req -> Client Raw clientWithRoute Proxy req httpMethod host = do performRequest httpMethod req (const True) host @@ -582,8 +581,8 @@ instance HasClient Raw where instance (MimeRender ct a, HasClient sublayout) => HasClient (ReqBody (ct ': cts) a :> sublayout) where - type Client' (ReqBody (ct ': cts) a :> sublayout) = - a -> Client' sublayout + type Client (ReqBody (ct ': cts) a :> sublayout) = + a -> Client sublayout clientWithRoute Proxy req body = clientWithRoute (Proxy :: Proxy sublayout) $ do @@ -592,7 +591,7 @@ instance (MimeRender ct a, HasClient sublayout) -- | Make the querying function append @path@ to the request path. instance (KnownSymbol path, HasClient sublayout) => HasClient (path :> sublayout) where - type Client' (path :> sublayout) = Client' sublayout + type Client (path :> sublayout) = Client sublayout clientWithRoute Proxy req = clientWithRoute (Proxy :: Proxy sublayout) $ diff --git a/servant-client/test/Servant/ClientSpec.hs b/servant-client/test/Servant/ClientSpec.hs index 9794f4dd..382b3c79 100644 --- a/servant-client/test/Servant/ClientSpec.hs +++ b/servant-client/test/Servant/ClientSpec.hs @@ -307,8 +307,8 @@ spec = do _ -> fail $ "expected InvalidContentTypeHeader, but got " <> show res data WrappedApi where - WrappedApi :: (HasServer (Canonicalize api), Server api ~ EitherT ServantErr IO a, - HasClient (Canonicalize api), Client api ~ (BaseUrl -> EitherT ServantError IO ())) => + WrappedApi :: (HasServer api, Server api ~ EitherT ServantErr IO a, + HasClient api, Client api ~ (BaseUrl -> EitherT ServantError IO ())) => Proxy api -> WrappedApi diff --git a/servant-docs/CHANGELOG.md b/servant-docs/CHANGELOG.md index 252ba296..469d6f51 100644 --- a/servant-docs/CHANGELOG.md +++ b/servant-docs/CHANGELOG.md @@ -5,7 +5,6 @@ * Render endpoints in a canonical order (https://github.com/haskell-servant/servant-docs/pull/15) * Remove ToJSON superclass from ToSample * Split out Internal module -* `Canonicalize` API types before generating the docs for them * Add support for response headers 0.3 diff --git a/servant-docs/src/Servant/Docs/Internal.hs b/servant-docs/src/Servant/Docs/Internal.hs index 8f195a28..cfe7e57a 100644 --- a/servant-docs/src/Servant/Docs/Internal.hs +++ b/servant-docs/src/Servant/Docs/Internal.hs @@ -291,8 +291,8 @@ makeLenses ''Action -- | Generate the docs for a given API that implements 'HasDocs'. This is the -- default way to create documentation. -docs :: HasDocs (Canonicalize layout) => Proxy layout -> API -docs p = docsFor (canonicalize p) (defEndpoint, defAction) +docs :: HasDocs layout => Proxy layout -> API +docs p = docsFor p (defEndpoint, defAction) -- | Closed type family, check if endpoint is exactly within API. @@ -336,11 +336,7 @@ extraInfo p action = -- 'extraInfo'. -- -- If you only want to add an introduction, use 'docsWithIntros'. -docsWith :: HasDocs (Canonicalize layout) - => [DocIntro] - -> ExtraInfo layout - -> Proxy layout - -> API +docsWith :: HasDocs layout => [DocIntro] -> ExtraInfo layout -> Proxy layout -> API docsWith intros (ExtraInfo endpoints) p = docs p & apiIntros <>~ intros & apiEndpoints %~ HM.unionWith combineAction endpoints @@ -348,7 +344,7 @@ docsWith intros (ExtraInfo endpoints) p = -- | Generate the docs for a given API that implements 'HasDocs' with with any -- number of introduction(s) -docsWithIntros :: HasDocs (Canonicalize layout) => [DocIntro] -> Proxy layout -> API +docsWithIntros :: HasDocs layout => [DocIntro] -> Proxy layout -> API docsWithIntros intros = docsWith intros mempty -- | The class that abstracts away the impact of API combinators diff --git a/servant-jquery/src/Servant/JQuery.hs b/servant-jquery/src/Servant/JQuery.hs index 4460e0e9..729a3fd9 100644 --- a/servant-jquery/src/Servant/JQuery.hs +++ b/servant-jquery/src/Servant/JQuery.hs @@ -26,8 +26,8 @@ import Data.Proxy import Servant.API import Servant.JQuery.Internal -jquery :: HasJQ (Canonicalize layout) => Proxy layout -> JQ layout -jquery p = jqueryFor (canonicalize p) defReq +jquery :: HasJQ layout => Proxy layout -> JQ layout +jquery p = jqueryFor p defReq -- js codegen generateJS :: AjaxReq -> String @@ -112,6 +112,5 @@ instance GenerateCode rest => GenerateCode (AjaxReq :<|> rest) where -- | Directly generate all the javascript functions for your API -- from a 'Proxy' for your API type. You can then write it to -- a file or integrate it in a page, for example. -jsForAPI :: (HasJQ (Canonicalize api), GenerateCode (JQ api)) - => Proxy api -> String +jsForAPI :: (HasJQ api, GenerateCode (JQ api)) => Proxy api -> String jsForAPI p = jsFor (jquery p) diff --git a/servant-jquery/src/Servant/JQuery/Internal.hs b/servant-jquery/src/Servant/JQuery/Internal.hs index 7cfb6b89..85896c2b 100644 --- a/servant-jquery/src/Servant/JQuery/Internal.hs +++ b/servant-jquery/src/Servant/JQuery/Internal.hs @@ -194,14 +194,12 @@ type family Elem (a :: *) (ls::[*]) :: Constraint where Elem a (b ': list) = Elem a list class HasJQ (layout :: *) where - type JQ' layout :: * - jqueryFor :: Proxy layout -> AjaxReq -> JQ' layout - -type JQ layout = JQ' (Canonicalize layout) + type JQ layout :: * + jqueryFor :: Proxy layout -> AjaxReq -> JQ layout instance (HasJQ a, HasJQ b) => HasJQ (a :<|> b) where - type JQ' (a :<|> b) = JQ' a :<|> JQ' b + type JQ (a :<|> b) = JQ a :<|> JQ b jqueryFor Proxy req = jqueryFor (Proxy :: Proxy a) req @@ -209,7 +207,7 @@ instance (HasJQ a, HasJQ b) instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (Capture sym a :> sublayout) where - type JQ' (Capture sym a :> sublayout) = JQ' sublayout + type JQ (Capture sym a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -218,14 +216,14 @@ instance (KnownSymbol sym, HasJQ sublayout) where str = symbolVal (Proxy :: Proxy sym) instance HasJQ Delete where - type JQ' Delete = AjaxReq + type JQ Delete = AjaxReq jqueryFor Proxy req = req & funcName %~ ("delete" <>) & reqMethod .~ "DELETE" instance Elem JSON list => HasJQ (Get list a) where - type JQ' (Get list a) = AjaxReq + type JQ (Get list a) = AjaxReq jqueryFor Proxy req = req & funcName %~ ("get" <>) @@ -233,7 +231,7 @@ instance Elem JSON list => HasJQ (Get list a) where instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (Header sym a :> sublayout) where - type JQ' (Header sym a :> sublayout) = JQ' sublayout + type JQ (Header sym a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor subP (req & reqHeaders <>~ [HeaderArg hname]) @@ -242,14 +240,14 @@ instance (KnownSymbol sym, HasJQ sublayout) subP = Proxy :: Proxy sublayout instance Elem JSON list => HasJQ (Post list a) where - type JQ' (Post list a) = AjaxReq + type JQ (Post list a) = AjaxReq jqueryFor Proxy req = req & funcName %~ ("post" <>) & reqMethod .~ "POST" instance Elem JSON list => HasJQ (Put list a) where - type JQ' (Put list a) = AjaxReq + type JQ (Put list a) = AjaxReq jqueryFor Proxy req = req & funcName %~ ("put" <>) @@ -257,7 +255,7 @@ instance Elem JSON list => HasJQ (Put list a) where instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (QueryParam sym a :> sublayout) where - type JQ' (QueryParam sym a :> sublayout) = JQ' sublayout + type JQ (QueryParam sym a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -267,7 +265,7 @@ instance (KnownSymbol sym, HasJQ sublayout) instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (QueryParams sym a :> sublayout) where - type JQ' (QueryParams sym a :> sublayout) = JQ' sublayout + type JQ (QueryParams sym a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -277,7 +275,7 @@ instance (KnownSymbol sym, HasJQ sublayout) instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (QueryFlag sym :> sublayout) where - type JQ' (QueryFlag sym :> sublayout) = JQ' sublayout + type JQ (QueryFlag sym :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -287,7 +285,7 @@ instance (KnownSymbol sym, HasJQ sublayout) instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (MatrixParam sym a :> sublayout) where - type JQ' (MatrixParam sym a :> sublayout) = JQ' sublayout + type JQ (MatrixParam sym a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -298,7 +296,7 @@ instance (KnownSymbol sym, HasJQ sublayout) instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (MatrixParams sym a :> sublayout) where - type JQ' (MatrixParams sym a :> sublayout) = JQ' sublayout + type JQ (MatrixParams sym a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -308,7 +306,7 @@ instance (KnownSymbol sym, HasJQ sublayout) instance (KnownSymbol sym, HasJQ sublayout) => HasJQ (MatrixFlag sym :> sublayout) where - type JQ' (MatrixFlag sym :> sublayout) = JQ' sublayout + type JQ (MatrixFlag sym :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -317,14 +315,14 @@ instance (KnownSymbol sym, HasJQ sublayout) where str = symbolVal (Proxy :: Proxy sym) instance HasJQ Raw where - type JQ' Raw = Method -> AjaxReq + type JQ Raw = Method -> AjaxReq jqueryFor Proxy req method = req & funcName %~ ((toLower <$> method) <>) & reqMethod .~ method instance (Elem JSON list, HasJQ sublayout) => HasJQ (ReqBody list a :> sublayout) where - type JQ' (ReqBody list a :> sublayout) = JQ' sublayout + type JQ (ReqBody list a :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ @@ -332,7 +330,7 @@ instance (Elem JSON list, HasJQ sublayout) => HasJQ (ReqBody list a :> sublayout instance (KnownSymbol path, HasJQ sublayout) => HasJQ (path :> sublayout) where - type JQ' (path :> sublayout) = JQ' sublayout + type JQ (path :> sublayout) = JQ sublayout jqueryFor Proxy req = jqueryFor (Proxy :: Proxy sublayout) $ diff --git a/servant-server/CHANGELOG.md b/servant-server/CHANGELOG.md index 161e66c2..9b9f30b6 100644 --- a/servant-server/CHANGELOG.md +++ b/servant-server/CHANGELOG.md @@ -5,7 +5,6 @@ * Support for `Accept`/`Content-type` headers and for the content-type aware combinators in *servant-0.3* * Export `toApplication` from `Servant.Server` (https://github.com/haskell-servant/servant-server/pull/29) * Support other Monads than just `EitherT (Int, String) IO` (https://github.com/haskell-servant/servant-server/pull/21) -* Canonicalize API types before generating the handler types with `Server` * Make methods return status code 204 if they return () (https://github.com/haskell-servant/servant-server/issues/28) * Add server support for response headers diff --git a/servant-server/src/Servant/Server.hs b/servant-server/src/Servant/Server.hs index 94245f2f..6e28d99e 100644 --- a/servant-server/src/Servant/Server.hs +++ b/servant-server/src/Servant/Server.hs @@ -15,7 +15,6 @@ module Servant.Server , -- * Handlers for all standard combinators HasServer(..) , Server - , ServerT -- * Enter -- $enterDoc @@ -80,7 +79,6 @@ module Servant.Server import Data.Proxy (Proxy) import Network.Wai (Application) -import Servant.API (Canonicalize, canonicalize) import Servant.Server.Internal import Servant.Server.Internal.Enter import Servant.Server.Internal.ServantErr @@ -109,8 +107,8 @@ import Servant.Server.Internal.ServantErr -- > main :: IO () -- > main = Network.Wai.Handler.Warp.run 8080 app -- -serve :: HasServer (Canonicalize layout) => Proxy layout -> Server layout -> Application -serve p server = toApplication (route (canonicalize p) server) +serve :: HasServer layout => Proxy layout -> Server layout -> Application +serve p server = toApplication (route p server) -- Documentation diff --git a/servant-server/src/Servant/Server/Internal.hs b/servant-server/src/Servant/Server/Internal.hs index fad9c66f..a712e757 100644 --- a/servant-server/src/Servant/Server/Internal.hs +++ b/servant-server/src/Servant/Server/Internal.hs @@ -38,7 +38,7 @@ import Network.Wai (Application, Request, Response, requestMethod, responseLBS, strictRequestBody) import Servant.API ((:<|>) (..), (:>), Capture, - Canonicalize, Delete, Get, Header, + Delete, Get, Header, MatrixFlag, MatrixParam, MatrixParams, Patch, Post, Put, QueryFlag, QueryParam, QueryParams, Raw, @@ -177,13 +177,11 @@ processedPathInfo r = where pinfo = parsePathInfo r class HasServer layout where - type ServerT' layout (m :: * -> *) :: * + type ServerT layout (m :: * -> *) :: * - route :: Proxy layout -> Server' layout -> RoutingApplication + route :: Proxy layout -> Server layout -> RoutingApplication -type Server layout = Server' (Canonicalize layout) -type Server' layout = ServerT' layout (EitherT ServantErr IO) -type ServerT layout m = ServerT' (Canonicalize layout) m +type Server layout = ServerT layout (EitherT ServantErr IO) -- * Instances @@ -200,7 +198,7 @@ type ServerT layout m = ServerT' (Canonicalize layout) m -- > postBook book = ... instance (HasServer a, HasServer b) => HasServer (a :<|> b) where - type ServerT' (a :<|> b) m = ServerT' a m :<|> ServerT' b m + type ServerT (a :<|> b) m = ServerT a m :<|> ServerT b m route Proxy (a :<|> b) request respond = route pa a request $ \mResponse -> @@ -234,8 +232,8 @@ captured _ = fromText instance (KnownSymbol capture, FromText a, HasServer sublayout) => HasServer (Capture capture a :> sublayout) where - type ServerT' (Capture capture a :> sublayout) m = - a -> ServerT' sublayout m + type ServerT (Capture capture a :> sublayout) m = + a -> ServerT sublayout m route Proxy subserver request respond = case processedPathInfo request of (first : rest) @@ -262,7 +260,7 @@ instance (KnownSymbol capture, FromText a, HasServer sublayout) -- are not met. instance HasServer Delete where - type ServerT' Delete m = m () + type ServerT Delete m = m () route Proxy action request respond | pathIsEmpty request && requestMethod request == methodDelete = do @@ -293,7 +291,7 @@ instance #endif ( AllCTRender ctypes a ) => HasServer (Get ctypes a) where - type ServerT' (Get ctypes a) m = m a + type ServerT (Get ctypes a) m = m a route Proxy action request respond | pathIsEmpty request && requestMethod request == methodGet = do @@ -317,7 +315,7 @@ instance #endif HasServer (Get ctypes ()) where - type ServerT' (Get ctypes ()) m = m () + type ServerT (Get ctypes ()) m = m () route Proxy action request respond | pathIsEmpty request && requestMethod request == methodGet = do @@ -337,7 +335,7 @@ instance ( GetHeaders (Headers h v), AllCTRender ctypes v ) => HasServer (Get ctypes (Headers h v)) where - type ServerT' (Get ctypes (Headers h v)) m = m (Headers h v) + type ServerT (Get ctypes (Headers h v)) m = m (Headers h v) route Proxy action request respond | pathIsEmpty request && requestMethod request == methodGet = do @@ -378,8 +376,8 @@ instance instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (Header sym a :> sublayout) where - type ServerT' (Header sym a :> sublayout) m = - Maybe a -> ServerT' sublayout m + type ServerT (Header sym a :> sublayout) m = + Maybe a -> ServerT sublayout m route Proxy subserver request respond = do let mheader = fromText . decodeUtf8 =<< lookup str (requestHeaders request) @@ -407,7 +405,7 @@ instance ( AllCTRender ctypes a ) => HasServer (Post ctypes a) where - type ServerT' (Post ctypes a) m = m a + type ServerT (Post ctypes a) m = m a route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPost = do @@ -430,7 +428,7 @@ instance #endif HasServer (Post ctypes ()) where - type ServerT' (Post ctypes ()) m = m () + type ServerT (Post ctypes ()) m = m () route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPost = do @@ -450,7 +448,7 @@ instance ( GetHeaders (Headers h v), AllCTRender ctypes v ) => HasServer (Post ctypes (Headers h v)) where - type ServerT' (Post ctypes (Headers h v)) m = m (Headers h v) + type ServerT (Post ctypes (Headers h v)) m = m (Headers h v) route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPost = do @@ -487,7 +485,7 @@ instance #endif ( AllCTRender ctypes a) => HasServer (Put ctypes a) where - type ServerT' (Put ctypes a) m = m a + type ServerT (Put ctypes a) m = m a route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPut = do @@ -510,7 +508,7 @@ instance #endif HasServer (Put ctypes ()) where - type ServerT' (Put ctypes ()) m = m () + type ServerT (Put ctypes ()) m = m () route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPut = do @@ -530,7 +528,7 @@ instance ( GetHeaders (Headers h v), AllCTRender ctypes v ) => HasServer (Put ctypes (Headers h v)) where - type ServerT' (Put ctypes (Headers h v)) m = m (Headers h v) + type ServerT (Put ctypes (Headers h v)) m = m (Headers h v) route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPut = do @@ -565,7 +563,7 @@ instance #endif ( AllCTRender ctypes a) => HasServer (Patch ctypes a) where - type ServerT' (Patch ctypes a) m = m a + type ServerT (Patch ctypes a) m = m a route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPatch = do @@ -588,7 +586,7 @@ instance #endif HasServer (Patch ctypes ()) where - type ServerT' (Patch ctypes ()) m = m () + type ServerT (Patch ctypes ()) m = m () route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPatch = do @@ -608,7 +606,7 @@ instance ( GetHeaders (Headers h v), AllCTRender ctypes v ) => HasServer (Patch ctypes (Headers h v)) where - type ServerT' (Patch ctypes (Headers h v)) m = m (Headers h v) + type ServerT (Patch ctypes (Headers h v)) m = m (Headers h v) route Proxy action request respond | pathIsEmpty request && requestMethod request == methodPatch = do @@ -650,8 +648,8 @@ instance instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParam sym a :> sublayout) where - type ServerT' (QueryParam sym a :> sublayout) m = - Maybe a -> ServerT' sublayout m + type ServerT (QueryParam sym a :> sublayout) m = + Maybe a -> ServerT sublayout m route Proxy subserver request respond = do let querytext = parseQueryText $ rawQueryString request @@ -688,8 +686,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout) instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (QueryParams sym a :> sublayout) where - type ServerT' (QueryParams sym a :> sublayout) m = - [a] -> ServerT' sublayout m + type ServerT (QueryParams sym a :> sublayout) m = + [a] -> ServerT sublayout m route Proxy subserver request respond = do let querytext = parseQueryText $ rawQueryString request @@ -721,8 +719,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout) instance (KnownSymbol sym, HasServer sublayout) => HasServer (QueryFlag sym :> sublayout) where - type ServerT' (QueryFlag sym :> sublayout) m = - Bool -> ServerT' sublayout m + type ServerT (QueryFlag sym :> sublayout) m = + Bool -> ServerT sublayout m route Proxy subserver request respond = do let querytext = parseQueryText $ rawQueryString request @@ -764,8 +762,8 @@ parseMatrixText = parseQueryText instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (MatrixParam sym a :> sublayout) where - type ServerT' (MatrixParam sym a :> sublayout) m = - Maybe a -> ServerT' sublayout m + type ServerT (MatrixParam sym a :> sublayout) m = + Maybe a -> ServerT sublayout m route Proxy subserver request respond = case parsePathInfo request of (first : _) @@ -802,8 +800,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout) instance (KnownSymbol sym, FromText a, HasServer sublayout) => HasServer (MatrixParams sym a :> sublayout) where - type ServerT' (MatrixParams sym a :> sublayout) m = - [a] -> ServerT' sublayout m + type ServerT (MatrixParams sym a :> sublayout) m = + [a] -> ServerT sublayout m route Proxy subserver request respond = case parsePathInfo request of (first : _) @@ -836,8 +834,8 @@ instance (KnownSymbol sym, FromText a, HasServer sublayout) instance (KnownSymbol sym, HasServer sublayout) => HasServer (MatrixFlag sym :> sublayout) where - type ServerT' (MatrixFlag sym :> sublayout) m = - Bool -> ServerT' sublayout m + type ServerT (MatrixFlag sym :> sublayout) m = + Bool -> ServerT sublayout m route Proxy subserver request respond = case parsePathInfo request of (first : _) @@ -865,7 +863,7 @@ instance (KnownSymbol sym, HasServer sublayout) -- > server = serveDirectory "/var/www/images" instance HasServer Raw where - type ServerT' Raw m = Application + type ServerT Raw m = Application route Proxy rawApplication request respond = rawApplication request (respond . succeedWith) @@ -893,8 +891,8 @@ instance HasServer Raw where instance ( AllCTUnrender list a, HasServer sublayout ) => HasServer (ReqBody list a :> sublayout) where - type ServerT' (ReqBody list a :> sublayout) m = - a -> ServerT' sublayout m + type ServerT (ReqBody list a :> sublayout) m = + a -> ServerT sublayout m route Proxy subserver request respond = do -- See HTTP RFC 2616, section 7.2.1 @@ -914,7 +912,7 @@ instance ( AllCTUnrender list a, HasServer sublayout -- pass the rest of the request path to @sublayout@. instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout) where - type ServerT' (path :> sublayout) m = ServerT' sublayout m + type ServerT (path :> sublayout) m = ServerT sublayout m route Proxy subserver request respond = case processedPathInfo request of (first : rest) diff --git a/servant/CHANGELOG.md b/servant/CHANGELOG.md index 146daee5..80c864f9 100644 --- a/servant/CHANGELOG.md +++ b/servant/CHANGELOG.md @@ -1,6 +1,5 @@ 0.3 --- -* Add a `Canonicalize` type family that distributes all `:>`s inside `:<|>`s to get to the canonical type of an API -- which is then used in all other packages to avoid weird handler types in *servant-server*. * Multiple content-type/accept support for all the relevant combinators * Provide *JSON*, *PlainText*, *OctetStream* and *FormUrlEncoded* content types out of the box * Type-safe link generation to API endpoints diff --git a/servant/src/Servant/API.hs b/servant/src/Servant/API.hs index 6fb97a6c..a7912564 100644 --- a/servant/src/Servant/API.hs +++ b/servant/src/Servant/API.hs @@ -49,10 +49,6 @@ module Servant.API ( module Servant.Common.Text, -- | Classes and instances for types that can be converted to and from @Text@ - -- * Canonicalizing (flattening) API types - Canonicalize, - canonicalize, - -- * Utilities module Servant.Utils.Links, -- | Type-safe internal URIs @@ -88,33 +84,3 @@ import Servant.Common.Text (FromText (..), ToText (..)) import Servant.Utils.Links (HasLink (..), IsElem, IsElem', URI (..), safeLink) --- | Turn an API type into its canonical form. --- --- The canonical form of an API type is basically the all-flattened form --- of the original type. More formally, it takes a type as input and hands you --- back an /equivalent/ type formed of toplevel `:<|>`-separated chains of `:>`s, --- i.e with all `:>`s distributed inside the `:<|>`s. --- --- It basically turns: --- --- > "hello" :> (Get Hello :<|> ReqBody Hello :> Put Hello) --- --- into --- --- > ("hello" :> Get Hello) :<|> ("hello" :> ReqBody Hello :> Put Hello) --- --- i.e distributing all ':>'-separated bits into the subsequent ':<|>'s. -type family Canonicalize api :: * where - -- requires UndecidableInstances - Canonicalize (a :> (b :<|> c)) = a :> Canonicalize b :<|> a :> Canonicalize c - Canonicalize ((a :<|> b) :> c) = a :> Canonicalize c :<|> b :> Canonicalize c - Canonicalize (a :> b) = Redex b (Canonicalize b) a - Canonicalize (a :<|> b) = Canonicalize a :<|> Canonicalize b - Canonicalize a = a - -type family Redex a b c :: * where - Redex a a first = Canonicalize first :> a - Redex a b first = Canonicalize (first :> b) - -canonicalize :: Proxy layout -> Proxy (Canonicalize layout) -canonicalize Proxy = Proxy