{-# OPTIONS_GHC -fno-warn-orphans #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- Module: Alerta.ServantExtras -- -- Additions to Servant needed to cope with the peculiarities of -- alerta's REST API. -------------------------------------------------------------------------------- module Alerta.ServantExtras ( FieldQueries ) where import Alerta.Types (FieldQuery, MatchType (..)) import Data.List import Data.Monoid ((<>)) import Data.Proxy import qualified Data.Text as T import Servant.API ((:>)) #if MIN_VERSION_servant_client(0,12,0) import Servant.Client.Core (HasClient (..), Request, appendToQueryString) #define REQ Request #else import Servant.Client import Servant.Common.Req (Req, appendToQueryString) #define REQ Req #endif import Web.HttpApiData -- | We need this because Alerta for some reason requires `field` and `field!` -- parameters to be joined together with a comma rather than passed in the -- usual way. instance {-# OVERLAPPABLE #-} ToHttpApiData a => ToHttpApiData [a] where toQueryParam = T.intercalate "," . map toQueryParam data FieldQueries #if !MIN_VERSION_servant_client(0,12,0) instance HasClient api => HasClient (FieldQueries :> api) where type Client (FieldQueries :> api) = [FieldQuery] -> Client api clientWithRoute Proxy req fqs = clientWithRoute (Proxy :: Proxy api) $ foldl' (flip applyFQ) req fqs #else instance HasClient m api => HasClient m (FieldQueries :> api) where type Client m (FieldQueries :> api) = [FieldQuery] -> Client m api clientWithRoute m Proxy req fqs = clientWithRoute m (Proxy :: Proxy api) $ foldl' (flip applyFQ) req fqs #endif applyFQ :: FieldQuery -> REQ -> REQ applyFQ (attr, txt, t, b) = appendToQueryString k (Just v) where k = toUrlPiece attr <> suffix v = prefix <> txt suffix = if b then "" else "!" prefix = case t of Regex -> "~" Literal -> ""