{-# LANGUAGE DataKinds     #-}
{-# LANGUAGE PolyKinds     #-}
{-# LANGUAGE RankNTypes    #-}
{-# LANGUAGE TypeOperators #-}
module Servant.Server.Internal.ErrorFormatter
  ( ErrorFormatters(..)
  , ErrorFormatter
  , NotFoundErrorFormatter
  , DefaultErrorFormatters
  , defaultErrorFormatters
  , MkContextWithErrorFormatter
  , mkContextWithErrorFormatter
  ) where
import           Data.String.Conversions
                 (cs)
import           Data.Typeable
import           Network.Wai.Internal
                 (Request)
import           Servant.API
                 (Capture, ReqBody)
import           Servant.Server.Internal.Context
import           Servant.Server.Internal.ServerError
type DefaultErrorFormatters = '[ErrorFormatters]
data ErrorFormatters = ErrorFormatters
  { 
    bodyParserErrorFormatter :: ErrorFormatter
    
  , urlParseErrorFormatter :: ErrorFormatter
    
  , headerParseErrorFormatter :: ErrorFormatter
    
  , notFoundErrorFormatter :: NotFoundErrorFormatter
  }
defaultErrorFormatters :: ErrorFormatters
defaultErrorFormatters = ErrorFormatters
  { bodyParserErrorFormatter = err400Formatter
  , urlParseErrorFormatter = err400Formatter
  , headerParseErrorFormatter = err400Formatter
  , notFoundErrorFormatter = const err404
  }
type ErrorFormatter = TypeRep -> Request -> String -> ServerError
type NotFoundErrorFormatter = Request -> ServerError
type MkContextWithErrorFormatter (ctx :: [*]) = ctx .++ DefaultErrorFormatters
mkContextWithErrorFormatter :: forall (ctx :: [*]). Context ctx -> Context (MkContextWithErrorFormatter ctx)
mkContextWithErrorFormatter ctx = ctx .++ (defaultErrorFormatters :. EmptyContext)
err400Formatter :: ErrorFormatter
err400Formatter _ _ e = err400 { errBody = cs e }
_RB :: Proxy ReqBody
_RB = Proxy
_C :: Proxy Capture
_C = Proxy
_CT :: Proxy Context
_CT = Proxy