{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- |
-- Module      : Servant.CLI.HasCLI
-- Copyright   : (c) Justin Le 2019
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
--
-- Main module providing underlying functionality for the command line
-- interface parser for servant API clients.
--
-- For the most part, you can ignore this module unless you're adding new
-- API combinators.
module Servant.CLI.HasCLI
  ( -- * Class
    HasCLI (..),

    -- * Context
    ContextFor (..),
    NamedContext (..),
    descendIntoNamedContext,
  )
where

import Data.Bifunctor
import qualified Data.ByteString.Builder as BSB
import qualified Data.ByteString.Lazy as BSL
import qualified Data.CaseInsensitive as CI
import Data.Char
import Data.Function
import Data.Kind
import Data.List (foldl', intercalate)
import qualified Data.List.NonEmpty as NE
import Data.Profunctor
import Data.Proxy
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.Vinyl hiding (rmap)
import Data.Void
import GHC.TypeLits hiding (Mod)
import Options.Applicative
import Servant.API hiding (addHeader)
import Servant.API.Modifiers
import Servant.CLI.Internal.PStruct
import Servant.CLI.ParseBody
import Servant.Client.Core
import Servant.Docs.Internal hiding (Endpoint, Response)
import Text.Printf
import Type.Reflection

-- | Data family associating API combinators with contexts required to run
-- them.  These typically will be actions in @m@ that fetch/generate the
-- required data, and will only be "run" if the user selects an endpoint
-- that requires it through the command line interface.
data family ContextFor (m :: Type -> Type) :: Type -> Type

-- | Typeclass defining how each API combinator influences how a server can
-- be interacted with using command line options.
--
-- Note that query parameters and captures all require /servant-docs/
-- annotation instances, to allow for proper help messages.
--
-- Unless you are adding new combinators to be used with APIs, you can
-- ignore this class.
class HasCLI m api ctx where
  -- | The parsed type of the client request response.  Usually this will
  -- be a bunch of nested 'Either's for every API endpoint, nested
  -- according to the ':<|>'s in the API.
  type CLIResult (m :: Type -> Type) (api :: Type) :: Type

  -- | The type of a data structure to conveniently handle the results of
  -- all pontential endpoints.  This is useful because it is often
  -- tedious to handle the bunch of nested 'Either's that 'CLIResult'
  -- has.
  --
  -- It essentially lets you specify how to sort each potential
  -- endpoint's response into a single output value.
  --
  -- Usually this will be a bunch of nested ':<|>'s which handle each
  -- endpoint, according to the ':<|>'s in the API.  It mirrors the
  -- structure of 'Client' and 'Servant.Server.ServerT'.
  --
  -- Used with functions like 'Servant.CLI.parseHandleClient'.
  type CLIHandler (m :: Type -> Type) (api :: Type) (r :: Type) :: Type

  -- | Create a structure for a command line parser, which parses how to
  -- modify a 'Request' and perform an action, given an API and
  -- underlying monad.  Only meant for internal use; should be used
  -- through 'Servant.CLI.cliPStructWithContext' instead.
  --
  -- Takes a 'Rec' of actions to generate required items that cannot be
  -- passed via the command line (like authentication).  Pass in 'RNil'
  -- if no parameters are expected.  The actions will only be run if they
  -- are needed.
  cliPStructWithContext_ ::
    Proxy m ->
    Proxy api ->
    Rec (ContextFor m) ctx ->
    PStruct (Request -> m (CLIResult m api))

  -- | Handle all the possibilities in a 'CLIResult', by giving the
  -- appropriate 'CLIHandler'.
  cliHandler ::
    Proxy m ->
    Proxy api ->
    Proxy ctx ->
    CLIHandler m api r ->
    CLIResult m api ->
    r

-- | 'EmptyAPI' will always fail to parse.
--
-- The branch ending in 'EmptyAPI' will never be return, so if this is
-- combined using ':<|>', the branch will never end up on the side of
-- 'EmptyAPI'.
--
-- One can use 'absurd' to handle this branch as a part of 'CLIHandler'.
instance HasCLI m EmptyAPI ctx where
  type CLIResult m EmptyAPI = Void
  type CLIHandler m EmptyAPI r = Void -> r

  cliPStructWithContext_ :: Proxy m
-> Proxy EmptyAPI
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m EmptyAPI))
cliPStructWithContext_ Proxy m
_ Proxy EmptyAPI
_ Rec (ContextFor m) ctx
_ = PStruct (Request -> m Void)
PStruct (Request -> m (CLIResult m EmptyAPI))
forall a. Monoid a => a
mempty
  cliHandler :: forall r.
Proxy m
-> Proxy EmptyAPI
-> Proxy ctx
-> CLIHandler m EmptyAPI r
-> CLIResult m EmptyAPI
-> r
cliHandler Proxy m
_ Proxy EmptyAPI
_ Proxy ctx
_ = CLIHandler m EmptyAPI r -> CLIResult m EmptyAPI -> r
(CLIResult m EmptyAPI -> r) -> CLIResult m EmptyAPI -> r
forall a b. (a -> b) -> a -> b
($)

-- | Using alternation with ':<|>' provides an 'Either' between the two
-- results.
instance
  ( HasCLI m a ctx,
    HasCLI m b ctx,
    Functor m
  ) =>
  HasCLI m (a :<|> b) ctx
  where
  type CLIResult m (a :<|> b) = Either (CLIResult m a) (CLIResult m b)
  type CLIHandler m (a :<|> b) r = CLIHandler m a r :<|> CLIHandler m b r

  cliPStructWithContext_ :: Proxy m
-> Proxy (a :<|> b)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (a :<|> b)))
cliPStructWithContext_ Proxy m
pm Proxy (a :<|> b)
_ Rec (ContextFor m) ctx
p =
    (CLIResult m a -> Either (CLIResult m a) (CLIResult m b))
-> PStruct (Request -> m (CLIResult m a))
-> PStruct (Request -> m (Either (CLIResult m a) (CLIResult m b)))
forall {a} {b} {a}.
(a -> b) -> PStruct (a -> m a) -> PStruct (a -> m b)
dig CLIResult m a -> Either (CLIResult m a) (CLIResult m b)
forall a b. a -> Either a b
Left (Proxy m
-> Proxy a
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m a))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Rec (ContextFor m) ctx
p)
      PStruct (Request -> m (Either (CLIResult m a) (CLIResult m b)))
-> PStruct (Request -> m (Either (CLIResult m a) (CLIResult m b)))
-> PStruct (Request -> m (Either (CLIResult m a) (CLIResult m b)))
forall a. Semigroup a => a -> a -> a
<> (CLIResult m b -> Either (CLIResult m a) (CLIResult m b))
-> PStruct (Request -> m (CLIResult m b))
-> PStruct (Request -> m (Either (CLIResult m a) (CLIResult m b)))
forall {a} {b} {a}.
(a -> b) -> PStruct (a -> m a) -> PStruct (a -> m b)
dig CLIResult m b -> Either (CLIResult m a) (CLIResult m b)
forall a b. b -> Either a b
Right (Proxy m
-> Proxy b
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m b))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @b) Rec (ContextFor m) ctx
p)
    where
      dig :: (a -> b) -> PStruct (a -> m a) -> PStruct (a -> m b)
dig = ((a -> m a) -> a -> m b)
-> PStruct (a -> m a) -> PStruct (a -> m b)
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((a -> m a) -> a -> m b)
 -> PStruct (a -> m a) -> PStruct (a -> m b))
-> ((a -> b) -> (a -> m a) -> a -> m b)
-> (a -> b)
-> PStruct (a -> m a)
-> PStruct (a -> m b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (m a -> m b) -> (a -> m a) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap ((m a -> m b) -> (a -> m a) -> a -> m b)
-> ((a -> b) -> m a -> m b) -> (a -> b) -> (a -> m a) -> a -> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> m a -> m b
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

  cliHandler :: forall r.
Proxy m
-> Proxy (a :<|> b)
-> Proxy ctx
-> CLIHandler m (a :<|> b) r
-> CLIResult m (a :<|> b)
-> r
cliHandler Proxy m
pm Proxy (a :<|> b)
_ Proxy ctx
pc (CLIHandler m a r
hA :<|> CLIHandler m b r
hB) =
    (CLIResult m a -> r)
-> (CLIResult m b -> r)
-> Either (CLIResult m a) (CLIResult m b)
-> r
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
      (Proxy m
-> Proxy a -> Proxy ctx -> CLIHandler m a r -> CLIResult m a -> r
forall r.
Proxy m
-> Proxy a -> Proxy ctx -> CLIHandler m a r -> CLIResult m a -> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @a) Proxy ctx
pc CLIHandler m a r
hA)
      (Proxy m
-> Proxy b -> Proxy ctx -> CLIHandler m b r -> CLIResult m b -> r
forall r.
Proxy m
-> Proxy b -> Proxy ctx -> CLIHandler m b r -> CLIResult m b -> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @b) Proxy ctx
pc CLIHandler m b r
hB)

-- | A path component is interpreted as a "subcommand".
instance (KnownSymbol path, HasCLI m api ctx) => HasCLI m (path :> api) ctx where
  type CLIResult m (path :> api) = CLIResult m api
  type CLIHandler m (path :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (path :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (path :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (path :> api)
_ Rec (ContextFor m) ctx
p =
    String
pathstr
      String
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a. String -> PStruct a -> PStruct a
$:> (((Request -> m (CLIResult m api))
 -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Request -> m (CLIResult m api))
  -> Request -> m (CLIResult m api))
 -> PStruct (Request -> m (CLIResult m api))
 -> PStruct (Request -> m (CLIResult m api)))
-> ((Request -> Request)
    -> (Request -> m (CLIResult m api))
    -> Request
    -> m (CLIResult m api))
-> (Request -> Request)
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Request -> Request)
-> (Request -> m (CLIResult m api))
-> Request
-> m (CLIResult m api)
forall a b c. (a -> b) -> (b -> c) -> a -> c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap)
        (Builder -> Request -> Request
appendToPath (ByteString -> Builder
BSB.byteString (ByteString -> Builder) -> ByteString -> Builder
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
pathstr))
        (Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p)
    where
      pathstr :: String
pathstr = Proxy path -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @path)

  cliHandler :: forall r.
Proxy m
-> Proxy (path :> api)
-> Proxy ctx
-> CLIHandler m (path :> api) r
-> CLIResult m (path :> api)
-> r
cliHandler Proxy m
pm Proxy (path :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | A 'Capture' is interpreted as a positional required command line argument.
--
-- Note that these require 'ToCapture' instances from /servant-docs/, to
-- provide appropriate help messages.
instance
  ( FromHttpApiData a,
    ToHttpApiData a,
    Typeable a,
    ToCapture (Capture sym a),
    HasCLI m api ctx
  ) =>
  HasCLI m (Capture' mods sym a :> api) ctx
  where
  type CLIResult m (Capture' mods sym a :> api) = CLIResult m api
  type CLIHandler m (Capture' mods sym a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (Capture' mods sym a :> api)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request -> m (CLIResult m (Capture' mods sym a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (Capture' mods sym a :> api)
_ Rec (ContextFor m) ctx
p =
    Arg a
arg
      #:> fmap (.: addCapture) (cliPStructWithContext_ pm (Proxy @api) p)
    where
      addCapture :: a -> Request -> Request
addCapture = Builder -> Request -> Request
appendToPath (Builder -> Request -> Request)
-> (a -> Builder) -> a -> Request -> Request
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Builder
BSB.byteString (ByteString -> Builder) -> (a -> ByteString) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> (a -> Text) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece
      arg :: Arg a
arg =
        Arg
          { argName :: String
argName = String
_capSymbol,
            argDesc :: String
argDesc = String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"%s (%s)" String
_capDesc String
capType,
            argMeta :: String
argMeta = String -> String -> String
forall r. PrintfType r => String -> r
printf String
"<%s>" String
_capSymbol,
            argRead :: ReadM a
argRead = (String -> Either String a) -> ReadM a
forall a. (String -> Either String a) -> ReadM a
eitherReader ((String -> Either String a) -> ReadM a)
-> (String -> Either String a) -> ReadM a
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> Either Text a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> String
T.unpack (Either Text a -> Either String a)
-> (String -> Either Text a) -> String -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromHttpApiData a => Text -> Either Text a
parseUrlPiece @a (Text -> Either Text a)
-> (String -> Text) -> String -> Either Text a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
          }
      capType :: String
capType = TypeRep a -> String
forall a. Show a => a -> String
show (TypeRep a -> String) -> TypeRep a -> String
forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a
      DocCapture {String
_capSymbol :: String
_capDesc :: String
_capSymbol :: DocCapture -> String
_capDesc :: DocCapture -> String
..} = Proxy (Capture sym a) -> DocCapture
forall {k} (c :: k). ToCapture c => Proxy c -> DocCapture
toCapture (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(Capture sym a))

  cliHandler :: forall r.
Proxy m
-> Proxy (Capture' mods sym a :> api)
-> Proxy ctx
-> CLIHandler m (Capture' mods sym a :> api) r
-> CLIResult m (Capture' mods sym a :> api)
-> r
cliHandler Proxy m
pm Proxy (Capture' mods sym a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | A 'CaptureAll' is interpreted as arbitrarily many command line
-- arguments.  If there is more than one final endpoint method, the method
-- must be given as a command line option before beginning the arguments.
instance
  ( FromHttpApiData a,
    ToHttpApiData a,
    Typeable a,
    ToCapture (CaptureAll sym a),
    HasCLI m api ctx
  ) =>
  HasCLI m (CaptureAll sym a :> api) ctx
  where
  type CLIResult m (CaptureAll sym a :> api) = CLIResult m api
  type CLIHandler m (CaptureAll sym a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (CaptureAll sym a :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (CaptureAll sym a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (CaptureAll sym a :> api)
_ Rec (ContextFor m) ctx
p =
    Arg a
arg
      ##:> fmap (.: addCapture) (cliPStructWithContext_ pm (Proxy @api) p)
    where
      addCapture :: [a] -> Request -> Request
addCapture [a]
ps Request
req =
        (Request -> Builder -> Request) -> Request -> [Builder] -> Request
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
          ((Builder -> Request -> Request) -> Request -> Builder -> Request
forall a b c. (a -> b -> c) -> b -> a -> c
flip Builder -> Request -> Request
appendToPath)
          Request
req
          ((a -> Builder) -> [a] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (ByteString -> Builder
BSB.byteString (ByteString -> Builder) -> (a -> ByteString) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> (a -> Text) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Text
forall a. ToHttpApiData a => a -> Text
toUrlPiece) [a]
ps)
      arg :: Arg a
arg =
        Arg
          { argName :: String
argName = String
_capSymbol,
            argDesc :: String
argDesc = String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"%s (%s)" String
_capDesc String
capType,
            argMeta :: String
argMeta = String -> String -> String
forall r. PrintfType r => String -> r
printf String
"<%s>" String
_capSymbol,
            argRead :: ReadM a
argRead = (String -> Either String a) -> ReadM a
forall a. (String -> Either String a) -> ReadM a
eitherReader ((String -> Either String a) -> ReadM a)
-> (String -> Either String a) -> ReadM a
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> Either Text a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> String
T.unpack (Either Text a -> Either String a)
-> (String -> Either Text a) -> String -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromHttpApiData a => Text -> Either Text a
parseUrlPiece @a (Text -> Either Text a)
-> (String -> Text) -> String -> Either Text a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
          }
      capType :: String
capType = TypeRep a -> String
forall a. Show a => a -> String
show (TypeRep a -> String) -> TypeRep a -> String
forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a
      DocCapture {String
_capSymbol :: DocCapture -> String
_capDesc :: DocCapture -> String
_capSymbol :: String
_capDesc :: String
..} = Proxy (CaptureAll sym a) -> DocCapture
forall {k} (c :: k). ToCapture c => Proxy c -> DocCapture
toCapture (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(CaptureAll sym a))

  cliHandler :: forall r.
Proxy m
-> Proxy (CaptureAll sym a :> api)
-> Proxy ctx
-> CLIHandler m (CaptureAll sym a :> api) r
-> CLIResult m (CaptureAll sym a :> api)
-> r
cliHandler Proxy m
pm Proxy (CaptureAll sym a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Query parameters are interpreted as command line options.
--
-- 'QueryParam'' arguments are associated with the action at their
-- endpoint.  After entering all path components and positional arguments,
-- the parser library will begin asking for arguments.
--
-- Note that these require 'ToParam' instances from /servant-docs/, to
-- provide appropriate help messages.
instance
  ( KnownSymbol sym,
    FromHttpApiData a,
    ToHttpApiData a,
    SBoolI (FoldRequired' 'False mods),
    Typeable a,
    ToParam (QueryParam' mods sym a),
    HasCLI m api ctx
  ) =>
  HasCLI m (QueryParam' mods sym a :> api) ctx
  where
  type CLIResult m (QueryParam' mods sym a :> api) = CLIResult m api
  type CLIHandler m (QueryParam' mods sym a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (QueryParam' mods sym a :> api)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request -> m (CLIResult m (QueryParam' mods sym a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (QueryParam' mods sym a :> api)
_ Rec (ContextFor m) ctx
p =
    Opt (RequiredArgument mods a)
opt
      Opt (RequiredArgument mods a)
-> PStruct
     (RequiredArgument mods a -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a b. Opt a -> PStruct (a -> b) -> PStruct b
?:> ((Request -> m (CLIResult m api))
 -> RequiredArgument mods a -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct
     (RequiredArgument mods a -> Request -> m (CLIResult m api))
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Request -> m (CLIResult m api))
-> (RequiredArgument mods a -> Request -> Request)
-> RequiredArgument mods a
-> Request
-> m (CLIResult m api)
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.: RequiredArgument mods a -> Request -> Request
addParam) (Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p)
    where
      addParam :: RequiredArgument mods a -> Request -> Request
      addParam :: RequiredArgument mods a -> Request -> Request
addParam = Proxy mods
-> (a -> Request -> Request)
-> (Maybe a -> Request -> Request)
-> RequiredArgument mods a
-> Request
-> Request
forall (mods :: [*]) a r.
SBoolI (FoldRequired mods) =>
Proxy mods
-> (a -> r) -> (Maybe a -> r) -> RequiredArgument mods a -> r
foldRequiredArgument (forall (t :: [*]). Proxy t
forall {k} (t :: k). Proxy t
Proxy @mods) a -> Request -> Request
add ((Request -> Request)
-> (a -> Request -> Request) -> Maybe a -> Request -> Request
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Request -> Request
forall a. a -> a
id a -> Request -> Request
add)
      add :: a -> Request -> Request
      add :: a -> Request -> Request
add a
param =
        Text -> Maybe ByteString -> Request -> Request
appendToQueryString
          (String -> Text
T.pack String
pName)
          (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ a -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam a
param))
      opt :: Opt (RequiredArgument mods a)
      opt :: Opt (RequiredArgument mods a)
opt =
        Opt
          { optName :: String
optName = String
pName,
            optDesc :: String
optDesc = String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"%s (%s)" String
_paramDesc String
valSpec,
            optMeta :: String
optMeta = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper String
pType,
            optVals :: Maybe (NonEmpty String)
optVals = [String] -> Maybe (NonEmpty String)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [String]
_paramValues,
            optRead :: Coyoneda OptRead (RequiredArgument mods a)
optRead = case forall (b :: Bool). SBoolI b => SBool b
sbool @(FoldRequired mods) of
              SBool (FoldRequired' 'False mods)
STrue -> ReadM (RequiredArgument mods a)
-> Coyoneda OptRead (RequiredArgument mods a)
forall a. ReadM a -> Coyoneda OptRead a
orRequired ReadM a
ReadM (RequiredArgument mods a)
r
              SBool (FoldRequired' 'False mods)
SFalse -> ReadM a -> Coyoneda OptRead (Maybe a)
forall a. ReadM a -> Coyoneda OptRead (Maybe a)
orOptional ReadM a
r
          }
      r :: ReadM a
r = (String -> Either String a) -> ReadM a
forall a. (String -> Either String a) -> ReadM a
eitherReader ((String -> Either String a) -> ReadM a)
-> (String -> Either String a) -> ReadM a
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> Either Text a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> String
T.unpack (Either Text a -> Either String a)
-> (String -> Either Text a) -> String -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam @a (Text -> Either Text a)
-> (String -> Text) -> String -> Either Text a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
      pType :: String
pType = TypeRep a -> String
forall a. Show a => a -> String
show (TypeRep a -> String) -> TypeRep a -> String
forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a
      valSpec :: String
valSpec
        | [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
_paramValues = String
pType
        | Bool
otherwise = String
"options: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
_paramValues
      pName :: String
pName = Proxy sym -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @sym)
      DocQueryParam {String
[String]
ParamKind
_paramDesc :: String
_paramValues :: [String]
_paramName :: String
_paramKind :: ParamKind
_paramName :: DocQueryParam -> String
_paramValues :: DocQueryParam -> [String]
_paramDesc :: DocQueryParam -> String
_paramKind :: DocQueryParam -> ParamKind
..} = Proxy (QueryParam' mods sym a) -> DocQueryParam
forall {k} (t :: k). ToParam t => Proxy t -> DocQueryParam
toParam (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(QueryParam' mods sym a))

  cliHandler :: forall r.
Proxy m
-> Proxy (QueryParam' mods sym a :> api)
-> Proxy ctx
-> CLIHandler m (QueryParam' mods sym a :> api) r
-> CLIResult m (QueryParam' mods sym a :> api)
-> r
cliHandler Proxy m
pm Proxy (QueryParam' mods sym a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Query flags are interpreted as command line flags/switches.
--
-- 'QueryFlag' arguments are associated with the action at their endpoint.
-- After entering all path components and positional arguments, the parser
-- library will begin asking for arguments.
--
-- Note that these require 'ToParam' instances from /servant-docs/, to
-- provide appropriate help messages.
instance
  ( KnownSymbol sym,
    ToParam (QueryFlag sym),
    HasCLI m api ctx
  ) =>
  HasCLI m (QueryFlag sym :> api) ctx
  where
  type CLIResult m (QueryFlag sym :> api) = CLIResult m api
  type CLIHandler m (QueryFlag sym :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (QueryFlag sym :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (QueryFlag sym :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (QueryFlag sym :> api)
_ Rec (ContextFor m) ctx
p =
    Opt Bool
opt
      Opt Bool
-> PStruct (Bool -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a b. Opt a -> PStruct (a -> b) -> PStruct b
?:> ((Request -> m (CLIResult m api))
 -> Bool -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Bool -> Request -> m (CLIResult m api))
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Request -> m (CLIResult m api))
-> (Bool -> Request -> Request)
-> Bool
-> Request
-> m (CLIResult m api)
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.: Bool -> Request -> Request
addParam) (Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p)
    where
      addParam :: Bool -> Request -> Request
      addParam :: Bool -> Request -> Request
addParam = \case
        Bool
True -> Text -> Maybe ByteString -> Request -> Request
appendToQueryString (String -> Text
T.pack String
pName) Maybe ByteString
forall a. Maybe a
Nothing
        Bool
False -> Request -> Request
forall a. a -> a
id
      opt :: Opt Bool
opt =
        Opt
          { optName :: String
optName = String
pName,
            optDesc :: String
optDesc = String
_paramDesc,
            optMeta :: String
optMeta = String -> String -> String
forall r. PrintfType r => String -> r
printf String
"<%s>" String
pName,
            optVals :: Maybe (NonEmpty String)
optVals = [String] -> Maybe (NonEmpty String)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [String]
_paramValues,
            optRead :: Coyoneda OptRead Bool
optRead = Coyoneda OptRead Bool
orSwitch
          }
      pName :: String
pName = Proxy sym -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @sym)
      DocQueryParam {String
[String]
ParamKind
_paramName :: DocQueryParam -> String
_paramValues :: DocQueryParam -> [String]
_paramDesc :: DocQueryParam -> String
_paramKind :: DocQueryParam -> ParamKind
_paramDesc :: String
_paramValues :: [String]
_paramName :: String
_paramKind :: ParamKind
..} = Proxy (QueryFlag sym) -> DocQueryParam
forall {k} (t :: k). ToParam t => Proxy t -> DocQueryParam
toParam (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(QueryFlag sym))

  cliHandler :: forall r.
Proxy m
-> Proxy (QueryFlag sym :> api)
-> Proxy ctx
-> CLIHandler m (QueryFlag sym :> api) r
-> CLIResult m (QueryFlag sym :> api)
-> r
cliHandler Proxy m
pm Proxy (QueryFlag sym :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Query parameters are interpreted as command line options, and so repeated
-- query parameters are repeated command line options.
--
-- 'QueryParams' are associated with the action at their endpoint.  After
-- entering all path components and positional arguments, the parser library
-- will begin asking for arguments.
--
-- Note that these require 'ToParam' instances from /servant-docs/, to
-- provide appropriate help messages.
instance
  ( ToHttpApiData a,
    ToParam (QueryParams sym a),
    KnownSymbol sym,
    Typeable a,
    FromHttpApiData a,
    HasCLI m api ctx
  ) =>
  HasCLI m (QueryParams sym a :> api) ctx
  where
  type CLIResult m (QueryParams sym a :> api) = CLIResult m api
  type CLIHandler m (QueryParams sym a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (QueryParams sym a :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (QueryParams sym a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (QueryParams sym a :> api)
_ Rec (ContextFor m) ctx
p =
    Opt [a]
opt
      Opt [a]
-> PStruct ([a] -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a b. Opt a -> PStruct (a -> b) -> PStruct b
?:> ((Request -> m (CLIResult m api))
 -> [a] -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct ([a] -> Request -> m (CLIResult m api))
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Request -> m (CLIResult m api))
-> ([a] -> Request -> Request)
-> [a]
-> Request
-> m (CLIResult m api)
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.: [a] -> Request -> Request
addParam) (Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p)
    where
      addParam :: [a] -> Request -> Request
      addParam :: [a] -> Request -> Request
addParam [a]
ps Request
req = (Request -> a -> Request) -> Request -> [a] -> Request
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' ((a -> Request -> Request) -> Request -> a -> Request
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> Request -> Request
add) Request
req [a]
ps
      add :: a -> Request -> Request
      add :: a -> Request -> Request
add a
param =
        Text -> Maybe ByteString -> Request -> Request
appendToQueryString
          (String -> Text
T.pack String
pName)
          (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ a -> Text
forall a. ToHttpApiData a => a -> Text
toQueryParam a
param))
      opt :: Opt [a]
      opt :: Opt [a]
opt =
        Opt
          { optName :: String
optName = String
pName,
            optDesc :: String
optDesc = String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"%s (%s)" String
_paramDesc String
valSpec,
            optMeta :: String
optMeta = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper String
pType,
            optVals :: Maybe (NonEmpty String)
optVals = [String] -> Maybe (NonEmpty String)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [String]
_paramValues,
            optRead :: Coyoneda OptRead [a]
optRead = ReadM a -> Coyoneda OptRead [a]
forall a. ReadM a -> Coyoneda OptRead [a]
orMany ReadM a
r
          }
      r :: ReadM a
r = (String -> Either String a) -> ReadM a
forall a. (String -> Either String a) -> ReadM a
eitherReader ((String -> Either String a) -> ReadM a)
-> (String -> Either String a) -> ReadM a
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> Either Text a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> String
T.unpack (Either Text a -> Either String a)
-> (String -> Either Text a) -> String -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FromHttpApiData a => Text -> Either Text a
parseQueryParam @a (Text -> Either Text a)
-> (String -> Text) -> String -> Either Text a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
      pType :: String
pType = TypeRep a -> String
forall a. Show a => a -> String
show (TypeRep a -> String) -> TypeRep a -> String
forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a
      valSpec :: String
valSpec
        | [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
_paramValues = String
pType
        | Bool
otherwise = String
"options: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
_paramValues
      pName :: String
pName = Proxy sym -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @sym)
      DocQueryParam {String
[String]
ParamKind
_paramName :: DocQueryParam -> String
_paramValues :: DocQueryParam -> [String]
_paramDesc :: DocQueryParam -> String
_paramKind :: DocQueryParam -> ParamKind
_paramDesc :: String
_paramValues :: [String]
_paramName :: String
_paramKind :: ParamKind
..} = Proxy (QueryParams sym a) -> DocQueryParam
forall {k} (t :: k). ToParam t => Proxy t -> DocQueryParam
toParam (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(QueryParams sym a))

  cliHandler :: forall r.
Proxy m
-> Proxy (QueryParams sym a :> api)
-> Proxy ctx
-> CLIHandler m (QueryParams sym a :> api) r
-> CLIResult m (QueryParams sym a :> api)
-> r
cliHandler Proxy m
pm Proxy (QueryParams sym a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Request body requirements are interpreted using 'ParseBody'.
--
-- Note if more than one 'ReqBody' is in an API endpoint, both parsers will
-- be "run", but only the final one will be used.  This shouldn't be an
-- issue, since multiple 'ReqBody's in a single endpoint should be
-- undefined behavior.
instance
  ( MimeRender ct a,
    ParseBody a,
    HasCLI m api ctx
  ) =>
  HasCLI m (ReqBody' mods (ct ': cts) a :> api) ctx
  where
  type CLIResult m (ReqBody' mods (ct ': cts) a :> api) = CLIResult m api
  type CLIHandler m (ReqBody' mods (ct ': cts) a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (ReqBody' mods (ct : cts) a :> api)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request -> m (CLIResult m (ReqBody' mods (ct : cts) a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (ReqBody' mods (ct : cts) a :> api)
_ Rec (ContextFor m) ctx
p =
    forall a. ParseBody a => Parser a
parseBody @a
      Parser a
-> PStruct (a -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a b. Parser a -> PStruct (a -> b) -> PStruct b
%:> ((Request -> m (CLIResult m api))
 -> a -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (a -> Request -> m (CLIResult m api))
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Request -> m (CLIResult m api))
-> (a -> Request -> Request) -> a -> Request -> m (CLIResult m api)
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.: a -> Request -> Request
addBody) (Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p)
    where
      addBody :: a -> Request -> Request
addBody a
b = ByteString -> MediaType -> Request -> Request
setRequestBodyLBS (Proxy ct -> a -> ByteString
forall {k} (ctype :: k) a.
MimeRender ctype a =>
Proxy ctype -> a -> ByteString
mimeRender Proxy ct
ctProxy a
b) (Proxy ct -> MediaType
forall {k} (ctype :: k). Accept ctype => Proxy ctype -> MediaType
contentType Proxy ct
ctProxy)
      ctProxy :: Proxy ct
ctProxy = forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @ct

  cliHandler :: forall r.
Proxy m
-> Proxy (ReqBody' mods (ct : cts) a :> api)
-> Proxy ctx
-> CLIHandler m (ReqBody' mods (ct : cts) a :> api) r
-> CLIResult m (ReqBody' mods (ct : cts) a :> api)
-> r
cliHandler Proxy m
pm Proxy (ReqBody' mods (ct : cts) a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Final actions are the result of specifying all necessary command line
-- positional arguments.
--
-- All command line options are associated with the final action at the end
-- of their endpoint/path.  They cannot be entered in "before" you arrive
-- at your final endpoint.
--
-- If more than one action (under a different method) exists
-- under the same endpoint/path, the method (@GET@, @POST@, etc.) will be
-- treated as an extra final command.  After that, you may begin entering
-- in options.
instance
  ( HasClient m (Verb method status cts' a),
    ReflectMethod method
  ) =>
  HasCLI m (Verb method status cts' a) ctx
  where
  type CLIResult m (Verb method status cts' a) = a
  type CLIHandler m (Verb method status cts' a) r = a -> r

  cliPStructWithContext_ :: Proxy m
-> Proxy (Verb method status cts' a)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (Verb method status cts' a)))
cliPStructWithContext_ Proxy m
pm Proxy (Verb method status cts' a)
pa Rec (ContextFor m) ctx
_ = ByteString -> (Request -> m a) -> PStruct (Request -> m a)
forall a. ByteString -> a -> PStruct a
endpoint (Proxy method -> ByteString
forall {k} (a :: k). ReflectMethod a => Proxy a -> ByteString
reflectMethod (forall (t :: k1). Proxy t
forall {k} (t :: k). Proxy t
Proxy @method)) (Proxy m
-> Proxy (Verb method status cts' a)
-> Request
-> Client m (Verb method status cts' a)
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
pm Proxy (Verb method status cts' a)
pa)
  cliHandler :: forall r.
Proxy m
-> Proxy (Verb method status cts' a)
-> Proxy ctx
-> CLIHandler m (Verb method status cts' a) r
-> CLIResult m (Verb method status cts' a)
-> r
cliHandler Proxy m
_ Proxy (Verb method status cts' a)
_ Proxy ctx
_ = CLIHandler m (Verb method status cts' a) r
-> CLIResult m (Verb method status cts' a) -> r
(CLIResult m (Verb method status cts' a) -> r)
-> CLIResult m (Verb method status cts' a) -> r
forall a b. (a -> b) -> a -> b
($)

-- | Final actions are the result of specifying all necessary command line
-- positional arguments.
--
-- All command line options are associated with the final action at the end
-- of their endpoint/path.  They cannot be entered in "before" you arrive
-- at your final endpoint.
--
-- If more than one action (under a different method) exists
-- under the same endpoint/path, the method (@GET@, @POST@, etc.) will be
-- treated as an extra final command.  After that, you may begin entering
-- in options.
instance
  ( RunClient m,
    ReflectMethod method
  ) =>
  HasCLI m (NoContentVerb method) ctx
  where
  type CLIResult m (NoContentVerb method) = NoContent
  type CLIHandler m (NoContentVerb method) r = r

  cliPStructWithContext_ :: Proxy m
-> Proxy (NoContentVerb method)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (NoContentVerb method)))
cliPStructWithContext_ Proxy m
pm Proxy (NoContentVerb method)
pa Rec (ContextFor m) ctx
_ = ByteString
-> (Request -> m NoContent) -> PStruct (Request -> m NoContent)
forall a. ByteString -> a -> PStruct a
endpoint (Proxy method -> ByteString
forall {k} (a :: k). ReflectMethod a => Proxy a -> ByteString
reflectMethod (forall (t :: k1). Proxy t
forall {k} (t :: k). Proxy t
Proxy @method)) (Proxy m
-> Proxy (NoContentVerb method)
-> Request
-> Client m (NoContentVerb method)
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
pm Proxy (NoContentVerb method)
pa)
  cliHandler :: forall r.
Proxy m
-> Proxy (NoContentVerb method)
-> Proxy ctx
-> CLIHandler m (NoContentVerb method) r
-> CLIResult m (NoContentVerb method)
-> r
cliHandler Proxy m
_ Proxy (NoContentVerb method)
_ Proxy ctx
_ = r -> NoContent -> r
CLIHandler m (NoContentVerb method) r
-> CLIResult m (NoContentVerb method) -> r
forall a b. a -> b -> a
const

-- | Same semantics in parsing command line options as 'Verb'.
instance
  ( RunStreamingClient m,
    MimeUnrender ct chunk,
    ReflectMethod method,
    FramingUnrender framing,
    FromSourceIO chunk a
  ) =>
  HasCLI m (Stream method status framing ct a) ctx
  where
  type CLIResult m (Stream method status framing ct a) = a
  type CLIHandler m (Stream method status framing ct a) r = a -> r
  cliPStructWithContext_ :: Proxy m
-> Proxy (Stream method status framing ct a)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request -> m (CLIResult m (Stream method status framing ct a)))
cliPStructWithContext_ Proxy m
pm Proxy (Stream method status framing ct a)
pa Rec (ContextFor m) ctx
_ = ByteString -> (Request -> m a) -> PStruct (Request -> m a)
forall a. ByteString -> a -> PStruct a
endpoint (Proxy method -> ByteString
forall {k} (a :: k). ReflectMethod a => Proxy a -> ByteString
reflectMethod (forall (t :: k1). Proxy t
forall {k} (t :: k). Proxy t
Proxy @method)) (Proxy m
-> Proxy (Stream method status framing ct a)
-> Request
-> Client m (Stream method status framing ct a)
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
pm Proxy (Stream method status framing ct a)
pa)
  cliHandler :: forall r.
Proxy m
-> Proxy (Stream method status framing ct a)
-> Proxy ctx
-> CLIHandler m (Stream method status framing ct a) r
-> CLIResult m (Stream method status framing ct a)
-> r
cliHandler Proxy m
_ Proxy (Stream method status framing ct a)
_ Proxy ctx
_ = CLIHandler m (Stream method status framing ct a) r
-> CLIResult m (Stream method status framing ct a) -> r
(CLIResult m (Stream method status framing ct a) -> r)
-> CLIResult m (Stream method status framing ct a) -> r
forall a b. (a -> b) -> a -> b
($)

newtype instance ContextFor m (StreamBody' mods framing ctype a) = GenStreamBody {forall (m :: * -> *) (mods :: [*]) framing ctype a.
ContextFor m (StreamBody' mods framing ctype a) -> m a
genStreamBody :: m a}

-- | As a part of @ctx@, asks for a streaming source @a@.
instance
  ( ToSourceIO chunk a,
    MimeRender ctype chunk,
    FramingRender framing,
    StreamBody' mods framing ctype a  ctx,
    HasCLI m api ctx,
    Monad m
  ) =>
  HasCLI m (StreamBody' mods framing ctype a :> api) ctx
  where
  type CLIResult m (StreamBody' mods framing ctype a :> api) = CLIResult m api
  type CLIHandler m (StreamBody' mods framing ctype a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (StreamBody' mods framing ctype a :> api)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request
      -> m (CLIResult m (StreamBody' mods framing ctype a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (StreamBody' mods framing ctype a :> api)
_ Rec (ContextFor m) ctx
p =
    m (Request -> Request)
-> (Request -> m (CLIResult m api))
-> Request
-> m (CLIResult m api)
forall (m :: * -> *) a b.
Monad m =>
m (a -> a) -> (a -> m b) -> a -> m b
withParamM (a -> Request -> Request
addBody (a -> Request -> Request) -> m a -> m (Request -> Request)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ContextFor m (StreamBody' mods framing ctype a) -> m a
forall (m :: * -> *) (mods :: [*]) framing ctype a.
ContextFor m (StreamBody' mods framing ctype a) -> m a
genStreamBody ContextFor m (StreamBody' mods framing ctype a)
mx)
      ((Request -> m (CLIResult m api))
 -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p
    where
      mx :: ContextFor m (StreamBody' mods framing ctype a)
      mx :: ContextFor m (StreamBody' mods framing ctype a)
mx = Rec (ContextFor m) ctx
-> ContextFor m (StreamBody' mods framing ctype a)
forall {k} (r :: k) (rs :: [k]) (f :: k -> *)
       (record :: (k -> *) -> [k] -> *).
(RecElem record r r rs rs (RIndex r rs), RecElemFCtx record f) =>
record f rs -> f r
rget Rec (ContextFor m) ctx
p
      addBody :: a -> Request -> Request
      addBody :: a -> Request -> Request
addBody a
x = RequestBody -> MediaType -> Request -> Request
setRequestBody RequestBody
rbs (Proxy ctype -> MediaType
forall {k} (ctype :: k). Accept ctype => Proxy ctype -> MediaType
contentType Proxy ctype
ctypeP)
        where
          ctypeP :: Proxy ctype
ctypeP = forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @ctype
          framingP :: Proxy framing
framingP = forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @framing
          rbs :: RequestBody
rbs =
            SourceIO ByteString -> RequestBody
RequestBodySource (SourceIO ByteString -> RequestBody)
-> SourceIO ByteString -> RequestBody
forall a b. (a -> b) -> a -> b
$
              Proxy framing
-> (chunk -> ByteString) -> SourceT IO chunk -> SourceIO ByteString
forall {k} (strategy :: k) (m :: * -> *) a.
(FramingRender strategy, Monad m) =>
Proxy strategy
-> (a -> ByteString) -> SourceT m a -> SourceT m ByteString
forall (m :: * -> *) a.
Monad m =>
Proxy framing
-> (a -> ByteString) -> SourceT m a -> SourceT m ByteString
framingRender
                Proxy framing
framingP
                (Proxy ctype -> chunk -> ByteString
forall {k} (ctype :: k) a.
MimeRender ctype a =>
Proxy ctype -> a -> ByteString
mimeRender Proxy ctype
ctypeP :: chunk -> BSL.ByteString)
                (a -> SourceT IO chunk
forall chunk a. ToSourceIO chunk a => a -> SourceIO chunk
toSourceIO a
x)
  cliHandler :: forall r.
Proxy m
-> Proxy (StreamBody' mods framing ctype a :> api)
-> Proxy ctx
-> CLIHandler m (StreamBody' mods framing ctype a :> api) r
-> CLIResult m (StreamBody' mods framing ctype a :> api)
-> r
cliHandler Proxy m
pm Proxy (StreamBody' mods framing ctype a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | A 'Header'' in the middle of a path is interpreted as a command line
-- argument, prefixed with "header".  For example,
-- @'Servant.API.Header.Header' "foo" 'Int'@ is an option for
-- @--header-foo@.
--
-- Like for 'QueryParam'',  arguments are associated with the action at
-- their endpoint.  After entering all path components and positional
-- arguments, the parser library will begin asking for arguments.
instance
  ( KnownSymbol sym,
    FromHttpApiData a,
    ToHttpApiData a,
    SBoolI (FoldRequired' 'False mods),
    Typeable a,
    HasCLI m api ctx
  ) =>
  HasCLI m (Header' mods sym a :> api) ctx
  where
  type CLIResult m (Header' mods sym a :> api) = CLIResult m api
  type CLIHandler m (Header' mods sym a :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (Header' mods sym a :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (Header' mods sym a :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (Header' mods sym a :> api)
_ Rec (ContextFor m) ctx
p =
    Opt (RequiredArgument mods a)
opt
      Opt (RequiredArgument mods a)
-> PStruct
     (RequiredArgument mods a -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a b. Opt a -> PStruct (a -> b) -> PStruct b
?:> ((Request -> m (CLIResult m api))
 -> RequiredArgument mods a -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct
     (RequiredArgument mods a -> Request -> m (CLIResult m api))
forall a b. (a -> b) -> PStruct a -> PStruct b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Request -> m (CLIResult m api))
-> (RequiredArgument mods a -> Request -> Request)
-> RequiredArgument mods a
-> Request
-> m (CLIResult m api)
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.: RequiredArgument mods a -> Request -> Request
addParam) (Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p)
    where
      addParam :: RequiredArgument mods a -> Request -> Request
      addParam :: RequiredArgument mods a -> Request -> Request
addParam = Proxy mods
-> (a -> Request -> Request)
-> (Maybe a -> Request -> Request)
-> RequiredArgument mods a
-> Request
-> Request
forall (mods :: [*]) a r.
SBoolI (FoldRequired mods) =>
Proxy mods
-> (a -> r) -> (Maybe a -> r) -> RequiredArgument mods a -> r
foldRequiredArgument (forall (t :: [*]). Proxy t
forall {k} (t :: k). Proxy t
Proxy @mods) a -> Request -> Request
add ((Request -> Request)
-> (a -> Request -> Request) -> Maybe a -> Request -> Request
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Request -> Request
forall a. a -> a
id a -> Request -> Request
add)
      add :: a -> Request -> Request
      add :: a -> Request -> Request
add = HeaderName -> a -> Request -> Request
forall a. ToHttpApiData a => HeaderName -> a -> Request -> Request
addHeader (ByteString -> HeaderName
forall s. FoldCase s => s -> CI s
CI.mk (ByteString -> HeaderName)
-> (String -> ByteString) -> String -> HeaderName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> HeaderName) -> String -> HeaderName
forall a b. (a -> b) -> a -> b
$ String
pName)
      opt :: Opt (RequiredArgument mods a)
      opt :: Opt (RequiredArgument mods a)
opt =
        Opt
          { optName :: String
optName = String -> String -> String
forall r. PrintfType r => String -> r
printf String
"header-%s" String
pName,
            optDesc :: String
optDesc = String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"Header data %s (%s)" String
pName String
pType,
            optMeta :: String
optMeta = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper String
pType,
            optVals :: Maybe (NonEmpty String)
optVals = Maybe (NonEmpty String)
forall a. Maybe a
Nothing,
            optRead :: Coyoneda OptRead (RequiredArgument mods a)
optRead = case forall (b :: Bool). SBoolI b => SBool b
sbool @(FoldRequired mods) of
              SBool (FoldRequired' 'False mods)
STrue -> ReadM (RequiredArgument mods a)
-> Coyoneda OptRead (RequiredArgument mods a)
forall a. ReadM a -> Coyoneda OptRead a
orRequired ReadM a
ReadM (RequiredArgument mods a)
r
              SBool (FoldRequired' 'False mods)
SFalse -> ReadM a -> Coyoneda OptRead (Maybe a)
forall a. ReadM a -> Coyoneda OptRead (Maybe a)
orOptional ReadM a
r
          }
      r :: ReadM a
      r :: ReadM a
r = (String -> Either String a) -> ReadM a
forall a. (String -> Either String a) -> ReadM a
eitherReader ((String -> Either String a) -> ReadM a)
-> (String -> Either String a) -> ReadM a
forall a b. (a -> b) -> a -> b
$ (Text -> String) -> Either Text a -> Either String a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first Text -> String
T.unpack (Either Text a -> Either String a)
-> (String -> Either Text a) -> String -> Either String a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either Text a
forall a. FromHttpApiData a => ByteString -> Either Text a
parseHeader (ByteString -> Either Text a)
-> (String -> ByteString) -> String -> Either Text a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
      pType :: String
pType = TypeRep a -> String
forall a. Show a => a -> String
show (TypeRep a -> String) -> TypeRep a -> String
forall a b. (a -> b) -> a -> b
$ forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
typeRep @a
      pName :: String
pName = Proxy sym -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @sym)

  cliHandler :: forall r.
Proxy m
-> Proxy (Header' mods sym a :> api)
-> Proxy ctx
-> CLIHandler m (Header' mods sym a :> api) r
-> CLIResult m (Header' mods sym a :> api)
-> r
cliHandler Proxy m
pm Proxy (Header' mods sym a :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Using 'HttpVersion' has no affect on CLI operations.
instance (HasCLI m api ctx) => HasCLI m (HttpVersion :> api) ctx where
  type CLIResult m (HttpVersion :> api) = CLIResult m api
  type CLIHandler m (HttpVersion :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (HttpVersion :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (HttpVersion :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (HttpVersion :> api)
_ = Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)
  cliHandler :: forall r.
Proxy m
-> Proxy (HttpVersion :> api)
-> Proxy ctx
-> CLIHandler m (HttpVersion :> api) r
-> CLIResult m (HttpVersion :> api)
-> r
cliHandler Proxy m
pm Proxy (HttpVersion :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | 'Summary' is displayed during @--help@ when it is reached while
-- navigating down subcommands.
instance (KnownSymbol desc, HasCLI m api ctx) => HasCLI m (Summary desc :> api) ctx where
  type CLIResult m (Summary desc :> api) = CLIResult m api
  type CLIHandler m (Summary desc :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (Summary desc :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (Summary desc :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (Summary desc :> api)
_ =
    [String]
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a. [String] -> PStruct a -> PStruct a
note [Proxy desc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @desc)]
      (PStruct (Request -> m (CLIResult m api))
 -> PStruct (Request -> m (CLIResult m api)))
-> (Rec (ContextFor m) ctx
    -> PStruct (Request -> m (CLIResult m api)))
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (Proxy api
forall {k} (t :: k). Proxy t
Proxy :: Proxy api)
  cliHandler :: forall r.
Proxy m
-> Proxy (Summary desc :> api)
-> Proxy ctx
-> CLIHandler m (Summary desc :> api) r
-> CLIResult m (Summary desc :> api)
-> r
cliHandler Proxy m
pm Proxy (Summary desc :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | 'Description' is displayed during @--help@ when it is reached while
-- navigating down subcommands.
instance (KnownSymbol desc, HasCLI m api ctx) => HasCLI m (Description desc :> api) ctx where
  type CLIResult m (Description desc :> api) = CLIResult m api
  type CLIHandler m (Description desc :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (Description desc :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (Description desc :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (Description desc :> api)
_ =
    [String]
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall a. [String] -> PStruct a -> PStruct a
note [Proxy desc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @desc)]
      (PStruct (Request -> m (CLIResult m api))
 -> PStruct (Request -> m (CLIResult m api)))
-> (Rec (ContextFor m) ctx
    -> PStruct (Request -> m (CLIResult m api)))
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (Proxy api
forall {k} (t :: k). Proxy t
Proxy :: Proxy api)
  cliHandler :: forall r.
Proxy m
-> Proxy (Description desc :> api)
-> Proxy ctx
-> CLIHandler m (Description desc :> api) r
-> CLIResult m (Description desc :> api)
-> r
cliHandler Proxy m
pm Proxy (Description desc :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Asks for method as a command line argument.  If any 'Verb' exists at
-- the same endpoint, it can only be accessed as an extra @RAW@ subcommand
-- (as if it had an extra path component labeled @"RAW"@).
instance (RunClient m) => HasCLI m Raw ctx where
  type CLIResult m Raw = Response
  type CLIHandler m Raw r = Response -> r

  cliPStructWithContext_ :: Proxy m
-> Proxy Raw
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m Raw))
cliPStructWithContext_ Proxy m
pm Proxy Raw
pa Rec (ContextFor m) ctx
_ = (ByteString -> Request -> m Response)
-> PStruct (Request -> m Response)
(ByteString -> Request -> m Response)
-> PStruct (Request -> m (CLIResult m Raw))
forall a. (ByteString -> a) -> PStruct a
rawEndpoint ((ByteString -> Request -> m Response)
 -> PStruct (Request -> m (CLIResult m Raw)))
-> ((Request -> ByteString -> m Response)
    -> ByteString -> Request -> m Response)
-> (Request -> ByteString -> m Response)
-> PStruct (Request -> m (CLIResult m Raw))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Request -> ByteString -> m Response)
-> ByteString -> Request -> m Response
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Request -> ByteString -> m Response)
 -> PStruct (Request -> m (CLIResult m Raw)))
-> (Request -> ByteString -> m Response)
-> PStruct (Request -> m (CLIResult m Raw))
forall a b. (a -> b) -> a -> b
$ Proxy m -> Proxy Raw -> Request -> Client m Raw
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
pm Proxy Raw
pa
  cliHandler :: forall r.
Proxy m
-> Proxy Raw
-> Proxy ctx
-> CLIHandler m Raw r
-> CLIResult m Raw
-> r
cliHandler Proxy m
_ Proxy Raw
_ Proxy ctx
_ = CLIHandler m Raw r -> CLIResult m Raw -> r
(CLIResult m Raw -> r) -> CLIResult m Raw -> r
forall a b. (a -> b) -> a -> b
($)

instance (HasCLI m api ctx) => HasCLI m (Vault :> api) ctx where
  type CLIResult m (Vault :> api) = CLIResult m api
  type CLIHandler m (Vault :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (Vault :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (Vault :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (Vault :> api)
_ = Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)
  cliHandler :: forall r.
Proxy m
-> Proxy (Vault :> api)
-> Proxy ctx
-> CLIHandler m (Vault :> api) r
-> CLIResult m (Vault :> api)
-> r
cliHandler Proxy m
pm Proxy (Vault :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

instance (HasCLI m api ctx) => HasCLI m (RemoteHost :> api) ctx where
  type CLIResult m (RemoteHost :> api) = CLIResult m api
  type CLIHandler m (RemoteHost :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (RemoteHost :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (RemoteHost :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (RemoteHost :> api)
_ = Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)
  cliHandler :: forall r.
Proxy m
-> Proxy (RemoteHost :> api)
-> Proxy ctx
-> CLIHandler m (RemoteHost :> api) r
-> CLIResult m (RemoteHost :> api)
-> r
cliHandler Proxy m
pm Proxy (RemoteHost :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

instance (HasCLI m api ctx) => HasCLI m (IsSecure :> api) ctx where
  type CLIResult m (IsSecure :> api) = CLIResult m api
  type CLIHandler m (IsSecure :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (IsSecure :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (IsSecure :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (IsSecure :> api)
_ = Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)
  cliHandler :: forall r.
Proxy m
-> Proxy (IsSecure :> api)
-> Proxy ctx
-> CLIHandler m (IsSecure :> api) r
-> CLIResult m (IsSecure :> api)
-> r
cliHandler Proxy m
pm Proxy (IsSecure :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Contains a subcontext that can be descended down into using
-- 'NamedContext'.  Mirrors 'Servant.Server.NamedContext'.
--
-- Useful for when you have multiple items with the same name within
-- a context; this essentially creates a namespace for context items.
newtype NamedContext m (name :: Symbol) (subContext :: [Type])
  = NamedContext (Rec (ContextFor m) subContext)

newtype instance ContextFor m (NamedContext m name subContext)
  = NC (NamedContext m name subContext)

-- | Allows you to access 'NamedContext's inside a context.
descendIntoNamedContext ::
  forall (name :: Symbol) context subContext m.
  (NamedContext m name subContext  context) =>
  Proxy name ->
  Rec (ContextFor m) context ->
  Rec (ContextFor m) subContext
descendIntoNamedContext :: forall (name :: Symbol) (context :: [*]) (subContext :: [*])
       (m :: * -> *).
(NamedContext m name subContext ∈ context) =>
Proxy name
-> Rec (ContextFor m) context -> Rec (ContextFor m) subContext
descendIntoNamedContext Proxy name
_ Rec (ContextFor m) context
p = Rec (ContextFor m) subContext
p'
  where
    NC (NamedContext Rec (ContextFor m) subContext
p' :: NamedContext m name subContext) = Rec (ContextFor m) context
-> ContextFor m (NamedContext m name subContext)
forall {k} (r :: k) (rs :: [k]) (f :: k -> *)
       (record :: (k -> *) -> [k] -> *).
(RecElem record r r rs rs (RIndex r rs), RecElemFCtx record f) =>
record f rs -> f r
rget Rec (ContextFor m) context
p

-- | Descend down a subcontext indexed by a given name.  Must be provided
-- when parsing within the context.
--
-- Useful for when you have multiple items with the same name within
-- a context; this essentially creates a namespace for context items.
instance
  ( NamedContext m name subctx  ctx,
    HasCLI m subapi subctx
  ) =>
  HasCLI m (WithNamedContext name subctx subapi) ctx
  where
  type CLIResult m (WithNamedContext name subctx subapi) = CLIResult m subapi
  type CLIHandler m (WithNamedContext name subctx subapi) r = CLIHandler m subapi r

  cliPStructWithContext_ :: Proxy m
-> Proxy (WithNamedContext name subctx subapi)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request -> m (CLIResult m (WithNamedContext name subctx subapi)))
cliPStructWithContext_ Proxy m
pm Proxy (WithNamedContext name subctx subapi)
_ =
    Proxy m
-> Proxy subapi
-> Rec (ContextFor m) subctx
-> PStruct (Request -> m (CLIResult m subapi))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @subapi)
      (Rec (ContextFor m) subctx
 -> PStruct (Request -> m (CLIResult m subapi)))
-> (Rec (ContextFor m) ctx -> Rec (ContextFor m) subctx)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m subapi))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (name :: Symbol) (context :: [*]) (subContext :: [*])
       (m :: * -> *).
(NamedContext m name subContext ∈ context) =>
Proxy name
-> Rec (ContextFor m) context -> Rec (ContextFor m) subContext
descendIntoNamedContext @_ @ctx @subctx (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @name)
  cliHandler :: forall r.
Proxy m
-> Proxy (WithNamedContext name subctx subapi)
-> Proxy ctx
-> CLIHandler m (WithNamedContext name subctx subapi) r
-> CLIResult m (WithNamedContext name subctx subapi)
-> r
cliHandler Proxy m
pm Proxy (WithNamedContext name subctx subapi)
_ Proxy ctx
_ = Proxy m
-> Proxy subapi
-> Proxy subctx
-> CLIHandler m subapi r
-> CLIResult m subapi
-> r
forall r.
Proxy m
-> Proxy subapi
-> Proxy subctx
-> CLIHandler m subapi r
-> CLIResult m subapi
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @subapi) (forall (t :: [*]). Proxy t
forall {k} (t :: k). Proxy t
Proxy @subctx)

newtype instance ContextFor m (AuthProtect tag) = GenAuthReq
  { forall k (m :: * -> *) (tag :: k).
ContextFor m (AuthProtect tag)
-> m (AuthenticatedRequest (AuthProtect tag))
genAuthReq :: m (AuthenticatedRequest (AuthProtect tag))
  }

-- | Add 'GenAuthReq' to the required context, meaning it must be
-- provided to allow the client to generate authentication data.  The
-- action will only be run if the user selects this endpoint via command
-- line arguments.
--
-- Please use a secure connection!
instance
  ( HasCLI m api ctx,
    AuthProtect tag  ctx,
    Monad m
  ) =>
  HasCLI m (AuthProtect tag :> api) ctx
  where
  type CLIResult m (AuthProtect tag :> api) = CLIResult m api
  type CLIHandler m (AuthProtect tag :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (AuthProtect tag :> api)
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m (AuthProtect tag :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (AuthProtect tag :> api)
_ Rec (ContextFor m) ctx
p =
    m (Request -> Request)
-> (Request -> m (CLIResult m api))
-> Request
-> m (CLIResult m api)
forall (m :: * -> *) a b.
Monad m =>
m (a -> a) -> (a -> m b) -> a -> m b
withParamM ((AuthClientData (AuthProtect tag)
 -> (AuthClientData (AuthProtect tag) -> Request -> Request)
 -> Request
 -> Request)
-> (AuthClientData (AuthProtect tag),
    AuthClientData (AuthProtect tag) -> Request -> Request)
-> Request
-> Request
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry AuthClientData (AuthProtect tag)
-> (AuthClientData (AuthProtect tag) -> Request -> Request)
-> Request
-> Request
forall a b. a -> (a -> b) -> b
(&) ((AuthClientData (AuthProtect tag),
  AuthClientData (AuthProtect tag) -> Request -> Request)
 -> Request -> Request)
-> (AuthenticatedRequest (AuthProtect tag)
    -> (AuthClientData (AuthProtect tag),
        AuthClientData (AuthProtect tag) -> Request -> Request))
-> AuthenticatedRequest (AuthProtect tag)
-> Request
-> Request
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AuthenticatedRequest (AuthProtect tag)
-> (AuthClientData (AuthProtect tag),
    AuthClientData (AuthProtect tag) -> Request -> Request)
forall a.
AuthenticatedRequest a
-> (AuthClientData a, AuthClientData a -> Request -> Request)
unAuthReq (AuthenticatedRequest (AuthProtect tag) -> Request -> Request)
-> m (AuthenticatedRequest (AuthProtect tag))
-> m (Request -> Request)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ContextFor m (AuthProtect tag)
-> m (AuthenticatedRequest (AuthProtect tag))
forall k (m :: * -> *) (tag :: k).
ContextFor m (AuthProtect tag)
-> m (AuthenticatedRequest (AuthProtect tag))
genAuthReq ContextFor m (AuthProtect tag)
md)
      ((Request -> m (CLIResult m api))
 -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p
    where
      md :: ContextFor m (AuthProtect tag)
      md :: ContextFor m (AuthProtect tag)
md = Rec (ContextFor m) ctx -> ContextFor m (AuthProtect tag)
forall {k} (r :: k) (rs :: [k]) (f :: k -> *)
       (record :: (k -> *) -> [k] -> *).
(RecElem record r r rs rs (RIndex r rs), RecElemFCtx record f) =>
record f rs -> f r
rget Rec (ContextFor m) ctx
p

  cliHandler :: forall r.
Proxy m
-> Proxy (AuthProtect tag :> api)
-> Proxy ctx
-> CLIHandler m (AuthProtect tag :> api) r
-> CLIResult m (AuthProtect tag :> api)
-> r
cliHandler Proxy m
pm Proxy (AuthProtect tag :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

newtype instance ContextFor m (BasicAuth realm usr) = GenBasicAuthData
  { forall (m :: * -> *) (realm :: Symbol) usr.
ContextFor m (BasicAuth realm usr) -> m BasicAuthData
genBasicAuthData :: m BasicAuthData
  }

-- | Add 'GenBasicAuthData' to the required context, meaning it must be
-- provided to allow the client to generate authentication data.  The
-- action will only be run if the user selects this endpoint via command
-- line arguments.
--
-- Please use a secure connection!
instance
  ( ToAuthInfo (BasicAuth realm usr),
    HasCLI m api ctx,
    BasicAuth realm usr  ctx,
    Monad m
  ) =>
  HasCLI m (BasicAuth realm usr :> api) ctx
  where
  type CLIResult m (BasicAuth realm usr :> api) = CLIResult m api
  type CLIHandler m (BasicAuth realm usr :> api) r = CLIHandler m api r

  cliPStructWithContext_ :: Proxy m
-> Proxy (BasicAuth realm usr :> api)
-> Rec (ContextFor m) ctx
-> PStruct
     (Request -> m (CLIResult m (BasicAuth realm usr :> api)))
cliPStructWithContext_ Proxy m
pm Proxy (BasicAuth realm usr :> api)
_ Rec (ContextFor m) ctx
p =
    [String]
-> PStruct
     (Request -> m (CLIResult m (BasicAuth realm usr :> api)))
-> PStruct
     (Request -> m (CLIResult m (BasicAuth realm usr :> api)))
forall a. [String] -> PStruct a -> PStruct a
note [String
infonote, String
reqnote] (PStruct (Request -> m (CLIResult m (BasicAuth realm usr :> api)))
 -> PStruct
      (Request -> m (CLIResult m (BasicAuth realm usr :> api))))
-> PStruct
     (Request -> m (CLIResult m (BasicAuth realm usr :> api)))
-> PStruct
     (Request -> m (CLIResult m (BasicAuth realm usr :> api)))
forall a b. (a -> b) -> a -> b
$
      m (Request -> Request)
-> (Request -> m (CLIResult m api))
-> Request
-> m (CLIResult m api)
forall (m :: * -> *) a b.
Monad m =>
m (a -> a) -> (a -> m b) -> a -> m b
withParamM (BasicAuthData -> Request -> Request
basicAuthReq (BasicAuthData -> Request -> Request)
-> m BasicAuthData -> m (Request -> Request)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ContextFor m (BasicAuth realm usr) -> m BasicAuthData
forall (m :: * -> *) (realm :: Symbol) usr.
ContextFor m (BasicAuth realm usr) -> m BasicAuthData
genBasicAuthData ContextFor m (BasicAuth realm usr)
md)
        ((Request -> m (CLIResult m api))
 -> Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
-> PStruct (Request -> m (CLIResult m api))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
forall (m :: * -> *) api (ctx :: [*]).
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Rec (ContextFor m) ctx
-> PStruct (Request -> m (CLIResult m api))
cliPStructWithContext_ Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api) Rec (ContextFor m) ctx
p
    where
      md :: ContextFor m (BasicAuth realm usr)
      md :: ContextFor m (BasicAuth realm usr)
md = Rec (ContextFor m) ctx -> ContextFor m (BasicAuth realm usr)
forall {k} (r :: k) (rs :: [k]) (f :: k -> *)
       (record :: (k -> *) -> [k] -> *).
(RecElem record r r rs rs (RIndex r rs), RecElemFCtx record f) =>
record f rs -> f r
rget Rec (ContextFor m) ctx
p
      infonote :: String
infonote = String
"Authentication required: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
_authIntro
      reqnote :: String
reqnote = String
"Required information: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
_authDataRequired

      DocAuthentication {String
_authIntro :: String
_authDataRequired :: String
_authIntro :: DocAuthentication -> String
_authDataRequired :: DocAuthentication -> String
..} = Proxy (BasicAuth realm usr) -> DocAuthentication
forall {k} (a :: k). ToAuthInfo a => Proxy a -> DocAuthentication
toAuthInfo (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @(BasicAuth realm usr))

  cliHandler :: forall r.
Proxy m
-> Proxy (BasicAuth realm usr :> api)
-> Proxy ctx
-> CLIHandler m (BasicAuth realm usr :> api) r
-> CLIResult m (BasicAuth realm usr :> api)
-> r
cliHandler Proxy m
pm Proxy (BasicAuth realm usr :> api)
_ = Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall r.
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
forall (m :: * -> *) api (ctx :: [*]) r.
HasCLI m api ctx =>
Proxy m
-> Proxy api
-> Proxy ctx
-> CLIHandler m api r
-> CLIResult m api
-> r
cliHandler Proxy m
pm (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @api)

-- | Helper for mapping parameter generators
withParamM ::
  (Monad m) =>
  m (a -> a) ->
  (a -> m b) ->
  a ->
  m b
withParamM :: forall (m :: * -> *) a b.
Monad m =>
m (a -> a) -> (a -> m b) -> a -> m b
withParamM m (a -> a)
mf a -> m b
g a
x = do
  a -> a
f <- m (a -> a)
mf
  a -> m b
g (a -> a
f a
x)

-- | Two-argument function composition
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(c -> d
f .: :: forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.: a -> b -> c
g) a
x b
y = c -> d
f (a -> b -> c
g a
x b
y)