{- |
Module      : Servant.API.Routes.Response
Copyright   : (c) Frederick Pringle, 2025
License     : BSD-3-Clause
Maintainer  : freddyjepringle@gmail.com

Term-level representation of the responses that Servant endpoints can return.
-}
module Servant.API.Routes.Response
  ( Responses
  , unResponses
  , noResponse
  , oneResponse
  , oneOfResponses
  , Response
  , responseType
  , responseHeaders
  , responses
  , HasResponse (..)
  , AllHasResponse (..)
  )
where

import Lens.Micro
import "this" Servant.API.Routes.Internal.Response
import "this" Servant.API.Routes.Internal.Some

-- | The endpoint will not return a response.
noResponse :: Responses
noResponse :: Responses
noResponse = Some Response -> Responses
Responses forall a. Some a
None

-- | There is only one possible response. Equivalent to a single @'Servant.API.ReqBody' _ a@.
oneResponse ::
  forall a.
  HasResponse a =>
  Responses
oneResponse :: forall a. HasResponse a => Responses
oneResponse = Some Response -> Responses
Responses forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Some a
One forall a b. (a -> b) -> a -> b
$ forall a. HasResponse a => Response
getResponse @a

{- | The endpoint may return one of multiple multiple (>1) responses.
Equivalent to a 'Servant.API.UVerb's with more than one type.
-}
oneOfResponses ::
  forall as.
  AllHasResponse as =>
  Responses
oneOfResponses :: forall (as :: [*]). AllHasResponse as => Responses
oneOfResponses = Some Response -> Responses
Responses forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Some a
Many forall a b. (a -> b) -> a -> b
$ forall (as :: [*]). AllHasResponse as => [Response]
getResponses @as

-- | Convenience optic to traverse over all the 'Response's within a 'Responses'.
responses :: Traversal' Responses Response
responses :: Traversal' Responses Response
responses = Lens' Responses (Some Response)
unResponses forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b.
Traversable f =>
Traversal (f a) (f b) a b
traversed