packages feed

servant-generic 0.1.0.0 → 0.1.0.1

raw patch · 3 files changed

+52/−12 lines, 3 filesdep +network-uridep ~basedep ~servantPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependencies added: network-uri

Dependency ranges changed: base, servant

API changes (from Hackage documentation)

+ Servant.Generic: data AsLink
+ Servant.Generic: fieldLink :: forall routes endpoint. (IsElem endpoint (ToServant (routes AsApi)), HasLink endpoint) => (routes AsApi -> endpoint) -> MkLink endpoint
+ Servant.Generic: fromServant :: GenericProduct a => ToServant a -> a
+ Servant.Generic: gfromServant :: GProduct f => GToServant f -> f p

Files

examples/Basic.hs view
@@ -2,17 +2,22 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-} +import           Data.Monoid import           Servant import           Servant.Generic import qualified Data.Text as T import           Data.Text (Text) import           Network.Wai.Handler.Warp (run) import           System.Timeout+import           Network.URI  data Site route = Site   { about :: route :-       "about" :> Get '[PlainText] Text+  , aboot :: route :-+      "aboot" :> Get '[PlainText] Text   , faq :: route :-       "faq" :> Get '[PlainText] Text   , subSite :: route :-@@ -39,6 +44,7 @@ siteServer :: Site AsServer siteServer = Site   { about = return "about"+  , aboot = return ("did you mean " <> showLink (fieldLink about) <> "?")   , faq = return "faq"   , subSite = toServant subSiteServer   , home = return "So long and thanks for all the :<|>"@@ -51,3 +57,12 @@   -- just to use this example as a test, run the server for one second   Nothing <- timeout 1000000 runServer   return ()++-- Servant changed the instance of MkLink in 0.10.+#if MIN_VERSION_servant(0,10,0)+showLink :: Link -> Text+showLink = toUrlPiece+#else+showLink :: URI -> Text+showLink uri = T.pack (uriToString id uri "")+#endif
servant-generic.cabal view
@@ -1,10 +1,7 @@--- Initial servant-generic.cabal generated by cabal init.  For further --- documentation, see http://haskell.org/cabal/users-guide/- name:                servant-generic-version:             0.1.0.0+version:             0.1.0.1 synopsis:            Specify Servant APIs with records.-description:         See README.+description:         Specify Servant APIs with records instead of @:\<|\>@ trees. See the <https://github.com/chpatrick/servant-generic/blob/master/README.md#tldr README> for more information. license:             MIT license-file:        LICENSE author:              Patrick Chilton@@ -23,7 +20,7 @@   exposed-modules:     Servant.Generic       -- other-modules:          -- other-extensions:    -  build-depends:       base >=4.7 && <4.10,+  build-depends:       base >=4.7 && <4.11,                        servant >= 0.7.1,                        servant-server >= 0.7.1   hs-source-dirs:      src@@ -34,9 +31,10 @@   type:                exitcode-stdio-1.0   main-is:             examples/Basic.hs   default-language:    Haskell2010-  build-depends:       base >=4.7 && <4.10,+  build-depends:       base >=4.7 && <4.11,                        servant >= 0.7.1,                        servant-server >= 0.7.1,                        servant-generic,                        text,-                       warp+                       warp,+                       network-uri
src/Servant/Generic.hs view
@@ -8,18 +8,23 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE DataKinds #-}-  +{-# LANGUAGE ScopedTypeVariables #-}+ module Servant.Generic   ( (:-)   , AsServerT   , AsServer   , AsApi+  , AsLink   , ToServant   , toServant+  , fromServant   , GenericProduct   -- * Internals   , GProduct(..)   , Generic(..)++  , fieldLink   ) where  import          GHC.Generics@@ -29,24 +34,28 @@ class GProduct f where   type GToServant f   gtoServant :: f p -> GToServant f+  gfromServant :: GToServant f -> f p  instance GProduct f => GProduct (M1 i c f) where   type GToServant (M1 i c f) = GToServant f   gtoServant (M1 x) = gtoServant x+  gfromServant x = M1 (gfromServant x)  instance (GProduct l, GProduct r) => GProduct (l :*: r) where   type GToServant (l :*: r) = GToServant l :<|> GToServant r   gtoServant (l :*: r) = gtoServant l :<|> gtoServant r+  gfromServant (l :<|> r) = gfromServant l :*: gfromServant r  instance GProduct (K1 i c) where   type GToServant (K1 i c) = c   gtoServant (K1 x) = x+  gfromServant x = K1 x  type GenericProduct a = (Generic a, GProduct (Rep a))  -- | Turns a generic product type into a linear tree of `:<|>` combinators. -- For example, given--- +-- -- @ --   data Foo route = Foo --     { foo :: route :-@@ -55,7 +64,7 @@ --         Get '[PlainText] Text --     } -- @--- +-- -- @ ToServant (Foo AsApi) ~ Get '[PlainText] Text :\<|\> Get '[PlainText] Text @ type ToServant a = GToServant (Rep a) @@ -63,16 +72,34 @@ toServant :: GenericProduct a => a -> ToServant a toServant = gtoServant . from +-- | Inverse of `toServant`.+--+-- This can be used to turn 'generated' values such as client functions into records.+--+-- You may need to provide a type signature for the /output/ type (your record type).+fromServant :: GenericProduct a => ToServant a -> a+fromServant = to . gfromServant+ -- | A type family that applies an appropriate type family to the @api@ parameter. -- For example, passing `AsApi` will leave @api@ untouched, while @`AsServerT` m@ will produce @`ServerT` api m@.  type family mode :- api-infixl 8 :-+infixl 3 :-  -- | A type that specifies that an API record contains an API definition. Only useful at type-level. data AsApi type instance AsApi :- api = api +-- | A type that specifies that an API record contains a set of links.+--+-- (Useful since servant 0.12)+data AsLink+type instance AsLink :- api = MkLink api+ -- | A type that specifies that an API record contains a server implementation. data AsServerT (m :: * -> *) type instance AsServerT m :- api = ServerT api m type AsServer = AsServerT Handler++-- | Given an API record field, create a link for that route. Only the field's type is used.+fieldLink :: forall routes endpoint. (IsElem endpoint (ToServant (routes AsApi)), HasLink endpoint) => (routes AsApi -> endpoint) -> MkLink endpoint+fieldLink _ = safeLink (Proxy :: Proxy (ToServant (routes AsApi))) (Proxy :: Proxy endpoint)