{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Servant.Server.JsonRpc
( module Servant.JsonRpc
) where
import Control.Monad.Error.Class (throwError)
import Data.Aeson (FromJSON, ToJSON)
import Data.Proxy (Proxy (..))
import GHC.TypeLits (KnownSymbol)
import Servant.API (NoContent)
import Servant.Server (HasServer (..), err400)
import Servant.JsonRpc
instance (KnownSymbol method, FromJSON p, ToJSON e, ToJSON r)
=> HasServer (JsonRpc method p e r) context where
type ServerT (JsonRpc method p e r) m = p -> m (Either (JsonRpcErr e) r)
route _ cx = route endpoint cx . fmap f
where
f x (Request _ p (Just ix)) = g ix <$> x p
f _ _ = throwError err400
g ix (Right r) = Result ix r
g ix (Left e) = Errors (Just ix) e
endpoint = Proxy @(JsonRpcEndpoint (JsonRpc method p e r))
hoistServerWithContext _ _ f x p = f $ x p
instance (KnownSymbol method, FromJSON p)
=> HasServer (JsonRpcNotification method p) context where
type ServerT (JsonRpcNotification method p) m = p -> m NoContent
route _ cx = route endpoint cx . fmap f
where
f x (Request _ p _) = x p
endpoint = Proxy @(JsonRpcEndpoint (JsonRpcNotification method p))
hoistServerWithContext _ _ f x p = f $ x p