{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Servant.API.Modifiers (
Required, Optional,
FoldRequired, FoldRequired',
Lenient, Strict,
FoldLenient, FoldLenient',
RequiredArgument,
foldRequiredArgument,
unfoldRequiredArgument,
RequestArgument,
unfoldRequestArgument,
) where
import Data.Proxy
(Proxy (..))
import Data.Singletons.Bool
(SBool (..), SBoolI (..))
import Data.Text
(Text)
import Data.Type.Bool
(If)
data Required
data Optional
type FoldRequired mods = FoldRequired' 'False mods
type family FoldRequired' (acc :: Bool) (mods :: [*]) :: Bool where
FoldRequired' acc '[] = acc
FoldRequired' acc (Required ': mods) = FoldRequired' 'True mods
FoldRequired' acc (Optional ': mods) = FoldRequired' 'False mods
FoldRequired' acc (mod ': mods) = FoldRequired' acc mods
data Lenient
data Strict
type FoldLenient mods = FoldLenient' 'False mods
type family FoldLenient' (acc :: Bool) (mods :: [*]) :: Bool where
FoldLenient' acc '[] = acc
FoldLenient' acc (Lenient ': mods) = FoldLenient' 'True mods
FoldLenient' acc (Strict ': mods) = FoldLenient' 'False mods
FoldLenient' acc (mod ': mods) = FoldLenient' acc mods
type RequiredArgument mods a = If (FoldRequired mods) a (Maybe a)
foldRequiredArgument
:: forall mods a r. (SBoolI (FoldRequired mods))
=> Proxy mods
-> (a -> r)
-> (Maybe a -> r)
-> RequiredArgument mods a
-> r
foldRequiredArgument :: forall (mods :: [*]) a r.
SBoolI (FoldRequired mods) =>
Proxy mods
-> (a -> r) -> (Maybe a -> r) -> RequiredArgument mods a -> r
foldRequiredArgument Proxy mods
_ a -> r
f Maybe a -> r
g RequiredArgument mods a
mx =
case (forall (b :: Bool). SBoolI b => SBool b
sbool :: SBool (FoldRequired mods), RequiredArgument mods a
mx) of
(SBool (FoldRequired mods)
STrue, RequiredArgument mods a
x) -> a -> r
f RequiredArgument mods a
x
(SBool (FoldRequired mods)
SFalse, RequiredArgument mods a
x) -> Maybe a -> r
g RequiredArgument mods a
x
unfoldRequiredArgument
:: forall mods m a. (Monad m, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods))
=> Proxy mods
-> m (RequiredArgument mods a)
-> (Text -> m (RequiredArgument mods a))
-> Maybe (Either Text a)
-> m (RequiredArgument mods a)
unfoldRequiredArgument :: forall (mods :: [*]) (m :: * -> *) a.
(Monad m, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods)) =>
Proxy mods
-> m (RequiredArgument mods a)
-> (Text -> m (RequiredArgument mods a))
-> Maybe (Either Text a)
-> m (RequiredArgument mods a)
unfoldRequiredArgument Proxy mods
_ m (RequiredArgument mods a)
errReq Text -> m (RequiredArgument mods a)
errSt Maybe (Either Text a)
mex =
case (forall (b :: Bool). SBoolI b => SBool b
sbool :: SBool (FoldRequired mods), Maybe (Either Text a)
mex) of
(SBool (FoldRequired mods)
STrue, Maybe (Either Text a)
Nothing) -> m (RequiredArgument mods a)
errReq
(SBool (FoldRequired mods)
SFalse, Maybe (Either Text a)
Nothing) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
(SBool (FoldRequired mods)
STrue, Just Either Text a
ex) -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Text -> m (RequiredArgument mods a)
errSt forall (m :: * -> *) a. Monad m => a -> m a
return Either Text a
ex
(SBool (FoldRequired mods)
SFalse, Just Either Text a
ex) -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Text -> m (RequiredArgument mods a)
errSt (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just) Either Text a
ex
type RequestArgument mods a =
If (FoldRequired mods)
(If (FoldLenient mods) (Either Text a) a)
(Maybe (If (FoldLenient mods) (Either Text a) a))
unfoldRequestArgument
:: forall mods m a. (Monad m, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods))
=> Proxy mods
-> m (RequestArgument mods a)
-> (Text -> m (RequestArgument mods a))
-> Maybe (Either Text a)
-> m (RequestArgument mods a)
unfoldRequestArgument :: forall (mods :: [*]) (m :: * -> *) a.
(Monad m, SBoolI (FoldRequired mods), SBoolI (FoldLenient mods)) =>
Proxy mods
-> m (RequestArgument mods a)
-> (Text -> m (RequestArgument mods a))
-> Maybe (Either Text a)
-> m (RequestArgument mods a)
unfoldRequestArgument Proxy mods
_ m (RequestArgument mods a)
errReq Text -> m (RequestArgument mods a)
errSt Maybe (Either Text a)
mex =
case (forall (b :: Bool). SBoolI b => SBool b
sbool :: SBool (FoldRequired mods), Maybe (Either Text a)
mex, forall (b :: Bool). SBoolI b => SBool b
sbool :: SBool (FoldLenient mods)) of
(SBool (FoldRequired mods)
STrue, Maybe (Either Text a)
Nothing, SBool (FoldLenient mods)
_) -> m (RequestArgument mods a)
errReq
(SBool (FoldRequired mods)
SFalse, Maybe (Either Text a)
Nothing, SBool (FoldLenient mods)
_) -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
(SBool (FoldRequired mods)
STrue, Just Either Text a
ex, SBool (FoldLenient mods)
STrue) -> forall (m :: * -> *) a. Monad m => a -> m a
return Either Text a
ex
(SBool (FoldRequired mods)
STrue, Just Either Text a
ex, SBool (FoldLenient mods)
SFalse) -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Text -> m (RequestArgument mods a)
errSt forall (m :: * -> *) a. Monad m => a -> m a
return Either Text a
ex
(SBool (FoldRequired mods)
SFalse, Just Either Text a
ex, SBool (FoldLenient mods)
STrue) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just Either Text a
ex)
(SBool (FoldRequired mods)
SFalse, Just Either Text a
ex, SBool (FoldLenient mods)
SFalse) -> forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Text -> m (RequestArgument mods a)
errSt (forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just) Either Text a
ex