{-# LANGUAGE DataKinds #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Jordan.Servant
( JordanJSON,
ReportingRequestBody,
JordanQuery',
RequiredJordanQuery,
OptionalJordanQuery,
ViaJordan (..),
)
where
import Data.Attoparsec.ByteString.Lazy (parseOnly)
import Data.Proxy (Proxy (..))
import Data.Typeable (Proxy (..))
import Jordan.FromJSON.Attoparsec (attoparsecParser)
import Jordan.FromJSON.Class (FromJSON (..))
import Jordan.FromJSON.UnboxedReporting (parseOrReport)
import Jordan.Servant.Query
( JordanQuery',
OptionalJordanQuery,
RequiredJordanQuery,
)
import Jordan.Servant.Response (ViaJordan (..))
import Jordan.ToJSON.Builder (toJSONViaBuilder)
import Jordan.ToJSON.Class (ToJSON (..))
import Jordan.Types.JSONError (JSONError)
import Network.HTTP.Media (matchContent)
import Network.HTTP.Media.MediaType ((//), (/:))
import Network.HTTP.Types.Header (hContentType)
import Servant.API
( Accept (..),
HasLink (..),
MimeRender (..),
MimeUnrender (..),
type (:>),
)
data JordanJSON
instance Accept JordanJSON where
contentType :: Proxy JordanJSON -> MediaType
contentType Proxy JordanJSON
Proxy = ByteString
"application" ByteString -> ByteString -> MediaType
// ByteString
"json" MediaType -> (ByteString, ByteString) -> MediaType
/: (ByteString
"haskell-encoder", ByteString
"jordan") MediaType -> (ByteString, ByteString) -> MediaType
/: (ByteString
"encoding", ByteString
"utf-8")
contentTypes :: Proxy JordanJSON -> NonEmpty MediaType
contentTypes p :: Proxy JordanJSON
p@Proxy JordanJSON
Proxy =
MediaType -> NonEmpty MediaType
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Proxy JordanJSON -> MediaType
forall k (ctype :: k). Accept ctype => Proxy ctype -> MediaType
contentType Proxy JordanJSON
p)
NonEmpty MediaType -> NonEmpty MediaType -> NonEmpty MediaType
forall a. Semigroup a => a -> a -> a
<> MediaType -> NonEmpty MediaType
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ByteString
"application" ByteString -> ByteString -> MediaType
// ByteString
"json") MediaType -> (ByteString, ByteString) -> MediaType
/: (ByteString
"encoding", ByteString
"utf-8"))
NonEmpty MediaType -> NonEmpty MediaType -> NonEmpty MediaType
forall a. Semigroup a => a -> a -> a
<> MediaType -> NonEmpty MediaType
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString
"application" ByteString -> ByteString -> MediaType
// ByteString
"json")
instance (ToJSON a) => MimeRender JordanJSON a where
mimeRender :: Proxy JordanJSON -> a -> ByteString
mimeRender Proxy JordanJSON
Proxy = a -> ByteString
forall a. ToJSON a => a -> ByteString
toJSONViaBuilder
instance (FromJSON a) => MimeUnrender JordanJSON a where
mimeUnrender :: Proxy JordanJSON -> ByteString -> Either String a
mimeUnrender Proxy JordanJSON
Proxy = Parser a -> ByteString -> Either String a
forall a. Parser a -> ByteString -> Either String a
parseOnly Parser a
forall val. FromJSON val => Parser val
attoparsecParser
mimeUnrenderWithType :: Proxy JordanJSON -> MediaType -> ByteString -> Either String a
mimeUnrenderWithType Proxy JordanJSON
Proxy MediaType
_ = Parser a -> ByteString -> Either String a
forall a. Parser a -> ByteString -> Either String a
parseOnly Parser a
forall val. FromJSON val => Parser val
attoparsecParser
data ReportingRequestBody a
instance HasLink sub => HasLink (ReportingRequestBody a :> sub) where
type MkLink (ReportingRequestBody a :> sub) r = MkLink sub r
toLink :: (Link -> a)
-> Proxy (ReportingRequestBody a :> sub)
-> Link
-> MkLink (ReportingRequestBody a :> sub) a
toLink Link -> a
toA (Proxy (ReportingRequestBody a :> sub)
Proxy :: Proxy (ReportingRequestBody a :> sub)) = (Link -> a) -> Proxy sub -> Link -> MkLink sub a
forall k (endpoint :: k) a.
HasLink endpoint =>
(Link -> a) -> Proxy endpoint -> Link -> MkLink endpoint a
toLink Link -> a
toA (Proxy sub
forall k (t :: k). Proxy t
Proxy @sub)