2014-10-25 01:27:39 +02:00
|
|
|
{-# LANGUAGE PolyKinds #-}
|
|
|
|
{-# LANGUAGE TypeFamilies #-}
|
|
|
|
{-# LANGUAGE TypeOperators #-}
|
2014-10-28 09:04:27 +01:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2014-10-25 01:27:39 +02:00
|
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
module Servant.API.Capture where
|
|
|
|
|
|
|
|
import Data.Proxy
|
|
|
|
import Data.Text
|
|
|
|
import GHC.TypeLits
|
|
|
|
import Network.Wai
|
|
|
|
import Servant.API.Sub
|
|
|
|
import Servant.Client
|
2014-10-28 09:04:27 +01:00
|
|
|
import Servant.Docs
|
2014-10-25 01:27:39 +02:00
|
|
|
import Servant.Server
|
|
|
|
import Servant.Text
|
|
|
|
|
|
|
|
-- * Captures
|
|
|
|
data Capture sym a
|
|
|
|
|
|
|
|
captured :: FromText a => proxy (Capture sym a) -> Text -> Maybe a
|
|
|
|
captured _ = fromText
|
|
|
|
|
|
|
|
instance (KnownSymbol capture, FromText a, HasServer sublayout)
|
|
|
|
=> HasServer (Capture capture a :> sublayout) where
|
|
|
|
|
|
|
|
type Server (Capture capture a :> sublayout) =
|
|
|
|
a -> Server sublayout
|
|
|
|
|
2014-10-27 11:24:20 +01:00
|
|
|
route Proxy subserver globalPathInfo request respond = case pathInfo request of
|
2014-10-25 01:27:39 +02:00
|
|
|
(first : rest)
|
|
|
|
-> case captured captureProxy first of
|
2014-10-27 11:24:20 +01:00
|
|
|
Nothing -> respond Nothing
|
|
|
|
Just v -> route (Proxy :: Proxy sublayout) (subserver v) globalPathInfo request{
|
2014-10-25 01:27:39 +02:00
|
|
|
pathInfo = rest
|
2014-10-27 11:24:20 +01:00
|
|
|
} respond
|
|
|
|
_ -> respond Nothing
|
2014-10-25 01:27:39 +02:00
|
|
|
|
|
|
|
where captureProxy = Proxy :: Proxy (Capture capture a)
|
|
|
|
|
|
|
|
instance (KnownSymbol capture, ToText a, HasClient sublayout)
|
|
|
|
=> HasClient (Capture capture a :> sublayout) where
|
|
|
|
|
|
|
|
type Client (Capture capture a :> sublayout) =
|
|
|
|
a -> Client sublayout
|
|
|
|
|
|
|
|
clientWithRoute Proxy req val =
|
|
|
|
clientWithRoute (Proxy :: Proxy sublayout) $
|
|
|
|
appendToPath p req
|
|
|
|
|
|
|
|
where p = unpack (toText val)
|
2014-10-28 09:04:27 +01:00
|
|
|
|
|
|
|
instance (KnownSymbol sym, ToCapture (Capture sym a), HasDocs sublayout)
|
|
|
|
=> HasDocs (Capture sym a :> sublayout) where
|
|
|
|
|
|
|
|
docsFor Proxy (endpoint, action) =
|
|
|
|
docsFor sublayoutP (endpoint', action')
|
|
|
|
|
|
|
|
where sublayoutP = Proxy :: Proxy sublayout
|
|
|
|
captureP = Proxy :: Proxy (Capture sym a)
|
|
|
|
|
|
|
|
action' = over captures (|> toCapture captureP) action
|
|
|
|
endpoint' = over path (\p -> p++"/:"++symbolVal symP) endpoint
|
|
|
|
symP = Proxy :: Proxy sym
|