{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Servant.API.UVerb
  ( UVerb,
    HasStatus (StatusOf),
    statusOf,
    HasStatuses (Statuses, statuses),
    WithStatus (..),
    module Servant.API.UVerb.Union,
  )
where
import Data.Proxy (Proxy (Proxy))
import GHC.TypeLits (Nat)
import Network.HTTP.Types (Status, StdMethod)
import Servant.API.ContentTypes (JSON, PlainText, FormUrlEncoded, OctetStream, NoContent, MimeRender(mimeRender), MimeUnrender(mimeUnrender))
import Servant.API.Status (KnownStatus, statusVal)
import Servant.API.ResponseHeaders (Headers)
import Servant.API.UVerb.Union
class KnownStatus (StatusOf a) => HasStatus (a :: *) where
  type StatusOf (a :: *) :: Nat
statusOf :: forall a proxy. HasStatus a => proxy a -> Status
statusOf :: forall a (proxy :: * -> *). HasStatus a => proxy a -> Status
statusOf = forall a b. a -> b -> a
const (forall (n :: Nat) (proxy :: Nat -> *).
KnownStatus n =>
proxy n -> Status
statusVal (forall {k} (t :: k). Proxy t
Proxy :: Proxy (StatusOf a)))
instance HasStatus NoContent where
  type StatusOf NoContent = 204
class HasStatuses (as :: [*]) where
  type Statuses (as :: [*]) :: [Nat]
  statuses :: Proxy as -> [Status]
instance HasStatuses '[] where
  type Statuses '[] = '[]
  statuses :: Proxy '[] -> [Status]
statuses Proxy '[]
_ = []
instance (HasStatus a, HasStatuses as) => HasStatuses (a ': as) where
  type Statuses (a ': as) = StatusOf a ': Statuses as
  statuses :: Proxy (a : as) -> [Status]
statuses Proxy (a : as)
_ = forall a (proxy :: * -> *). HasStatus a => proxy a -> Status
statusOf (forall {k} (t :: k). Proxy t
Proxy :: Proxy a) forall a. a -> [a] -> [a]
: forall (as :: [*]). HasStatuses as => Proxy as -> [Status]
statuses (forall {k} (t :: k). Proxy t
Proxy :: Proxy as)
newtype WithStatus (k :: Nat) a = WithStatus a
  deriving (WithStatus k a -> WithStatus k a -> Bool
forall (k :: Nat) a.
Eq a =>
WithStatus k a -> WithStatus k a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WithStatus k a -> WithStatus k a -> Bool
$c/= :: forall (k :: Nat) a.
Eq a =>
WithStatus k a -> WithStatus k a -> Bool
== :: WithStatus k a -> WithStatus k a -> Bool
$c== :: forall (k :: Nat) a.
Eq a =>
WithStatus k a -> WithStatus k a -> Bool
Eq, Int -> WithStatus k a -> ShowS
forall (k :: Nat) a. Show a => Int -> WithStatus k a -> ShowS
forall (k :: Nat) a. Show a => [WithStatus k a] -> ShowS
forall (k :: Nat) a. Show a => WithStatus k a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WithStatus k a] -> ShowS
$cshowList :: forall (k :: Nat) a. Show a => [WithStatus k a] -> ShowS
show :: WithStatus k a -> String
$cshow :: forall (k :: Nat) a. Show a => WithStatus k a -> String
showsPrec :: Int -> WithStatus k a -> ShowS
$cshowsPrec :: forall (k :: Nat) a. Show a => Int -> WithStatus k a -> ShowS
Show)
instance KnownStatus n => HasStatus (WithStatus n a) where
  type StatusOf (WithStatus n a) = n
instance HasStatus a => HasStatus (Headers ls a) where
  type StatusOf (Headers ls a) = StatusOf a
data UVerb (method :: StdMethod) (contentTypes :: [*]) (as :: [*])
instance {-# OVERLAPPING #-} MimeRender JSON a => MimeRender JSON (WithStatus _status a) where
  mimeRender :: Proxy JSON -> WithStatus _status a -> ByteString
mimeRender Proxy JSON
contentTypeProxy (WithStatus a
a) = forall {k} (ctype :: k) a.
MimeRender ctype a =>
Proxy ctype -> a -> ByteString
mimeRender Proxy JSON
contentTypeProxy a
a
instance {-# OVERLAPPING #-} MimeRender PlainText a => MimeRender PlainText (WithStatus _status a) where
  mimeRender :: Proxy PlainText -> WithStatus _status a -> ByteString
mimeRender Proxy PlainText
contentTypeProxy (WithStatus a
a) = forall {k} (ctype :: k) a.
MimeRender ctype a =>
Proxy ctype -> a -> ByteString
mimeRender Proxy PlainText
contentTypeProxy a
a
instance {-# OVERLAPPING #-} MimeRender FormUrlEncoded a => MimeRender FormUrlEncoded (WithStatus _status a) where
  mimeRender :: Proxy FormUrlEncoded -> WithStatus _status a -> ByteString
mimeRender Proxy FormUrlEncoded
contentTypeProxy (WithStatus a
a) = forall {k} (ctype :: k) a.
MimeRender ctype a =>
Proxy ctype -> a -> ByteString
mimeRender Proxy FormUrlEncoded
contentTypeProxy a
a
instance {-# OVERLAPPING #-} MimeRender OctetStream a => MimeRender OctetStream (WithStatus _status a) where
  mimeRender :: Proxy OctetStream -> WithStatus _status a -> ByteString
mimeRender Proxy OctetStream
contentTypeProxy (WithStatus a
a) = forall {k} (ctype :: k) a.
MimeRender ctype a =>
Proxy ctype -> a -> ByteString
mimeRender Proxy OctetStream
contentTypeProxy a
a
instance {-# OVERLAPPING #-} MimeUnrender JSON a => MimeUnrender JSON (WithStatus _status a) where
  mimeUnrender :: Proxy JSON -> ByteString -> Either String (WithStatus _status a)
mimeUnrender Proxy JSON
contentTypeProxy ByteString
input = forall (k :: Nat) a. a -> WithStatus k a
WithStatus forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (ctype :: k) a.
MimeUnrender ctype a =>
Proxy ctype -> ByteString -> Either String a
mimeUnrender Proxy JSON
contentTypeProxy ByteString
input
instance {-# OVERLAPPING #-} MimeUnrender PlainText a => MimeUnrender PlainText (WithStatus _status a) where
  mimeUnrender :: Proxy PlainText
-> ByteString -> Either String (WithStatus _status a)
mimeUnrender Proxy PlainText
contentTypeProxy ByteString
input = forall (k :: Nat) a. a -> WithStatus k a
WithStatus forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (ctype :: k) a.
MimeUnrender ctype a =>
Proxy ctype -> ByteString -> Either String a
mimeUnrender Proxy PlainText
contentTypeProxy ByteString
input
instance {-# OVERLAPPING #-} MimeUnrender FormUrlEncoded a => MimeUnrender FormUrlEncoded (WithStatus _status a) where
  mimeUnrender :: Proxy FormUrlEncoded
-> ByteString -> Either String (WithStatus _status a)
mimeUnrender Proxy FormUrlEncoded
contentTypeProxy ByteString
input = forall (k :: Nat) a. a -> WithStatus k a
WithStatus forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (ctype :: k) a.
MimeUnrender ctype a =>
Proxy ctype -> ByteString -> Either String a
mimeUnrender Proxy FormUrlEncoded
contentTypeProxy ByteString
input
instance {-# OVERLAPPING #-} MimeUnrender OctetStream a => MimeUnrender OctetStream (WithStatus _status a) where
  mimeUnrender :: Proxy OctetStream
-> ByteString -> Either String (WithStatus _status a)
mimeUnrender Proxy OctetStream
contentTypeProxy ByteString
input = forall (k :: Nat) a. a -> WithStatus k a
WithStatus forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall {k} (ctype :: k) a.
MimeUnrender ctype a =>
Proxy ctype -> ByteString -> Either String a
mimeUnrender Proxy OctetStream
contentTypeProxy ByteString
input