2014-10-25 01:27:39 +02:00
|
|
|
{-# LANGUAGE PolyKinds #-}
|
|
|
|
{-# LANGUAGE TypeFamilies #-}
|
|
|
|
{-# LANGUAGE TypeOperators #-}
|
|
|
|
{-# LANGUAGE ScopedTypeVariables #-}
|
|
|
|
module Servant.API.Sub where
|
|
|
|
|
|
|
|
import Data.Proxy
|
|
|
|
import Data.String.Conversions
|
|
|
|
import GHC.TypeLits
|
|
|
|
import Network.Wai
|
|
|
|
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
|
2014-11-07 05:41:00 +01:00
|
|
|
import Servant.Utils.Req
|
2014-10-25 01:27:39 +02:00
|
|
|
|
|
|
|
-- | The contained API (second argument) can be found under @("/" ++ path)@
|
|
|
|
-- (path being the first argument).
|
|
|
|
data (path :: k) :> a = Proxy path :> a
|
|
|
|
infixr 9 :>
|
|
|
|
|
|
|
|
instance (KnownSymbol path, HasServer sublayout) => HasServer (path :> sublayout) where
|
|
|
|
type Server (path :> sublayout) = Server sublayout
|
2014-10-28 10:42:49 +01:00
|
|
|
route Proxy subserver request respond = case pathInfo request of
|
2014-10-25 01:27:39 +02:00
|
|
|
(first : rest)
|
|
|
|
| first == cs (symbolVal proxyPath)
|
2014-10-28 10:42:49 +01:00
|
|
|
-> route (Proxy :: Proxy sublayout) subserver request{
|
2014-10-25 01:27:39 +02:00
|
|
|
pathInfo = rest
|
2014-10-27 11:24:20 +01:00
|
|
|
} respond
|
2014-10-28 14:34:28 +01:00
|
|
|
_ -> respond $ failWith NotFound
|
2014-10-25 01:27:39 +02:00
|
|
|
|
|
|
|
where proxyPath = Proxy :: Proxy path
|
|
|
|
|
|
|
|
instance (KnownSymbol path, HasClient sublayout) => HasClient (path :> sublayout) where
|
|
|
|
type Client (path :> sublayout) = Client sublayout
|
|
|
|
|
|
|
|
clientWithRoute Proxy req =
|
|
|
|
clientWithRoute (Proxy :: Proxy sublayout) $
|
|
|
|
appendToPath p req
|
|
|
|
|
|
|
|
where p = symbolVal (Proxy :: Proxy path)
|
|
|
|
|
2014-10-28 09:04:27 +01:00
|
|
|
instance (KnownSymbol path, HasDocs sublayout) => HasDocs (path :> sublayout) where
|
|
|
|
|
|
|
|
docsFor Proxy (endpoint, action) =
|
|
|
|
docsFor sublayoutP (endpoint', action)
|
|
|
|
|
|
|
|
where sublayoutP = Proxy :: Proxy sublayout
|
|
|
|
endpoint' = endpoint & path <>~ symbolVal pa
|
|
|
|
pa = Proxy :: Proxy path
|