{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Admin.Components.ComponentsClass
( with
, Components(..)
) where
import Admin.Components.Component
import Admin.Components.ComponentDescription
import Admin.Components.ComponentList
import Admin.Components.Internal.TypeLevel
import Data.Version
import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)
import Servant
type ToServantAPI names api = (ManySymbolVal names, HasServer api '[])
class (ToServantAPI names apis) =>
Components a (names :: [Symbol]) apis
| a -> names apis
where
serveAll' :: a -> Server apis
describe :: a -> [ComponentDescription]
instance (KnownSymbol name, HasServer api '[]) =>
Components (Component name api) '[ name] (name :> api) where
serveAll' :: Component name api -> Server (name :> api)
serveAll' Component name api
c = Component name api -> Server api
forall (name :: Symbol) api. Component name api -> Server api
server Component name api
c
describe :: Component name api -> [ComponentDescription]
describe Component name api
c =
let n :: String
n = Proxy name -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy name
forall k (t :: k). Proxy t
Proxy :: Proxy name)
v :: Version
v = Component name api -> Version
forall (name :: Symbol) api. Component name api -> Version
version Component name api
c
in [String -> Version -> ComponentDescription
ComponentDescription String
n Version
v]
instance (ToServantAPI names apis) =>
Components (ComponentList names apis) names apis where
serveAll' :: ComponentList names apis -> Server apis
serveAll' ComponentList names apis
c = ComponentList names apis -> Server apis
forall (names :: [Symbol]) apis.
ComponentList names apis -> Server apis
serveAll ComponentList names apis
c
describe :: ComponentList names apis -> [ComponentDescription]
describe ComponentList names apis
c = ComponentList names apis -> [ComponentDescription]
forall (names :: [Symbol]) apis.
ManySymbolVal names =>
ComponentList names apis -> [ComponentDescription]
descriptionsOf ComponentList names apis
c
getVersions :: Components a names apis => a -> [Version]
getVersions :: a -> [Version]
getVersions = (ComponentDescription -> Version)
-> [ComponentDescription] -> [Version]
forall a b. (a -> b) -> [a] -> [b]
map ComponentDescription -> Version
componentVersion ([ComponentDescription] -> [Version])
-> (a -> [ComponentDescription]) -> a -> [Version]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [ComponentDescription]
forall a (names :: [Symbol]) apis.
Components a names apis =>
a -> [ComponentDescription]
describe
infixr 9 `with`
with ::
(Components a names apis)
=> Component name api
-> a
-> ComponentList (name : names) ((name :> api) :<|> apis)
with :: Component name api
-> a -> ComponentList (name : names) ((name :> api) :<|> apis)
with Component name api
new a
lst =
Server ((name :> api) :<|> apis)
-> [Version]
-> ComponentList (name : names) ((name :> api) :<|> apis)
forall (names :: [Symbol]) apis.
Server apis -> [Version] -> ComponentList names apis
ComponentList (Component name api -> Server api
forall (name :: Symbol) api. Component name api -> Server api
server Component name api
new Server api
-> ServerT apis Handler -> Server api :<|> ServerT apis Handler
forall a b. a -> b -> a :<|> b
:<|> a -> ServerT apis Handler
forall a (names :: [Symbol]) apis.
Components a names apis =>
a -> Server apis
serveAll' a
lst) (Component name api -> Version
forall (name :: Symbol) api. Component name api -> Version
version Component name api
new Version -> [Version] -> [Version]
forall a. a -> [a] -> [a]
: a -> [Version]
forall a (names :: [Symbol]) apis.
Components a names apis =>
a -> [Version]
getVersions a
lst)