{- |
Module      : Servant.API.Routes.Request
Copyright   : (c) Frederick Pringle, 2025
License     : BSD-3-Clause
Maintainer  : frederick.pringle@fpringle.com

Term-level representation of the request bodies that Servant endpoints expect.
-}
module Servant.API.Routes.Request
  ( Request
  , unRequest
  , noRequest
  , oneRequest
  , allOfRequests
  , requests
  )
where

import Data.Typeable
import Lens.Micro
import "this" Servant.API.Routes.Internal.Request
import "this" Servant.API.Routes.Internal.Some
import "this" Servant.API.Routes.Utils

-- | The endpoint doesn't expect a request body.
noRequest :: Request
noRequest :: Request
noRequest = Some TypeRep -> Request
Request Some TypeRep
forall a. Some a
None

{- | The request body can only be of one type. Equivalent to a single
@'Servant.API.ReqBody' _ a@.
-}
oneRequest ::
  forall a.
  (Typeable a) =>
  Request
oneRequest :: forall a. Typeable a => Request
oneRequest = Some TypeRep -> Request
Request (Some TypeRep -> Request)
-> (TypeRep -> Some TypeRep) -> TypeRep -> Request
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeRep -> Some TypeRep
forall a. a -> Some a
One (TypeRep -> Request) -> TypeRep -> Request
forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeRep
typeRepOf @a

{- | The endpoint expects the request body to be parsed as multiple (>1) types.
Equivalent to multiple 'Servant.API.ReqBody's chained with @:>@.
-}
allOfRequests ::
  forall as.
  (AllTypeable as) =>
  Request
allOfRequests :: forall (as :: [*]). AllTypeable as => Request
allOfRequests = Some TypeRep -> Request
Request (Some TypeRep -> Request)
-> ([TypeRep] -> Some TypeRep) -> [TypeRep] -> Request
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [TypeRep] -> Some TypeRep
forall a. [a] -> Some a
Many ([TypeRep] -> Request) -> [TypeRep] -> Request
forall a b. (a -> b) -> a -> b
$ forall (as :: [*]). AllTypeable as => [TypeRep]
typeReps @as

-- | Convenience optic to traverse over all the 'TypeRep's within a 'Request'.
requests :: Traversal' Request TypeRep
requests :: Traversal' Request TypeRep
requests = (Some TypeRep -> f (Some TypeRep)) -> Request -> f Request
Lens' Request (Some TypeRep)
unRequest ((Some TypeRep -> f (Some TypeRep)) -> Request -> f Request)
-> ((TypeRep -> f TypeRep) -> Some TypeRep -> f (Some TypeRep))
-> (TypeRep -> f TypeRep)
-> Request
-> f Request
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TypeRep -> f TypeRep) -> Some TypeRep -> f (Some TypeRep)
Traversal (Some TypeRep) (Some TypeRep) TypeRep TypeRep
forall (f :: * -> *) a b.
Traversable f =>
Traversal (f a) (f b) a b
traversed