-- | Provides a dynamic effect for optparse-applicative.
--
-- @since 0.1
module Effectful.Optparse.Dynamic
  ( -- * Effect
    Optparse (..),
    execParser,
    customExecParser,
    handleParseResult,

    -- ** Handler
    runOptparse,

    -- * Misc
    Utils.osPath,
    Utils.validOsPath,
  )
where

import Effectful
  ( Dispatch (Dynamic),
    DispatchOf,
    Eff,
    Effect,
    IOE,
    type (:>),
  )
import Effectful.Dispatch.Dynamic (HasCallStack, reinterpret_, send)
import Effectful.Dynamic.Utils (ShowEffect (showEffectCons))
import Effectful.Optparse.Static qualified as Static
import Effectful.Optparse.Utils qualified as Utils
import Options.Applicative (ParserInfo, ParserPrefs, ParserResult)

-- | Dynamic effect for optparse-applicative.
--
-- @since 0.1
data Optparse :: Effect where
  ExecParser :: ParserInfo a -> Optparse m a
  CustomExecParser :: ParserPrefs -> ParserInfo a -> Optparse m a
  HandleParseResult :: ParserResult a -> Optparse m a

-- | @since 0.1
type instance DispatchOf Optparse = Dynamic

-- | @since 0.1
instance ShowEffect Optparse where
  showEffectCons :: forall (m :: * -> *) a. Optparse m a -> String
showEffectCons = \case
    ExecParser ParserInfo a
_ -> String
"ExecParser"
    CustomExecParser ParserPrefs
_ ParserInfo a
_ -> String
"CustomExecParser"
    HandleParseResult ParserResult a
_ -> String
"HandleParseResult"

-- | Runs 'Optparse' in 'IO'.
--
-- @since 0.1
runOptparse ::
  ( HasCallStack,
    IOE :> es
  ) =>
  Eff (Optparse : es) a ->
  Eff es a
runOptparse :: forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, IOE :> es) =>
Eff (Optparse : es) a -> Eff es a
runOptparse = (Eff (Optparse : es) a -> Eff es a)
-> EffectHandler_ Optparse (Optparse : es)
-> Eff (Optparse : es) a
-> Eff es a
forall (e :: (* -> *) -> * -> *)
       (handlerEs :: [(* -> *) -> * -> *]) a (es :: [(* -> *) -> * -> *])
       b.
(HasCallStack, DispatchOf e ~ 'Dynamic) =>
(Eff handlerEs a -> Eff es b)
-> EffectHandler_ e handlerEs -> Eff (e : es) a -> Eff es b
reinterpret_ Eff (Optparse : es) a -> Eff es a
forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, IOE :> es) =>
Eff (Optparse : es) a -> Eff es a
Static.runOptparse (EffectHandler_ Optparse (Optparse : es)
 -> Eff (Optparse : es) a -> Eff es a)
-> EffectHandler_ Optparse (Optparse : es)
-> Eff (Optparse : es) a
-> Eff es a
forall a b. (a -> b) -> a -> b
$ \case
  ExecParser ParserInfo a
i -> ParserInfo a -> Eff (Optparse : es) a
forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, Optparse :> es) =>
ParserInfo a -> Eff es a
Static.execParser ParserInfo a
i
  CustomExecParser ParserPrefs
prefs ParserInfo a
i -> ParserPrefs -> ParserInfo a -> Eff (Optparse : es) a
forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, Optparse :> es) =>
ParserPrefs -> ParserInfo a -> Eff es a
Static.customExecParser ParserPrefs
prefs ParserInfo a
i
  HandleParseResult ParserResult a
r -> ParserResult a -> Eff (Optparse : es) a
forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, Optparse :> es) =>
ParserResult a -> Eff es a
Static.handleParseResult ParserResult a
r

-- | Lifted 'OA.execParser'.
--
-- @since 0.1
execParser :: (HasCallStack, Optparse :> es) => ParserInfo a -> Eff es a
execParser :: forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, Optparse :> es) =>
ParserInfo a -> Eff es a
execParser = Optparse (Eff es) a -> Eff es a
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Optparse (Eff es) a -> Eff es a)
-> (ParserInfo a -> Optparse (Eff es) a)
-> ParserInfo a
-> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParserInfo a -> Optparse (Eff es) a
forall a (m :: * -> *). ParserInfo a -> Optparse m a
ExecParser

-- | Lifted 'OA.customExecParser'.
--
-- @since 0.1
customExecParser ::
  (HasCallStack, Optparse :> es) =>
  ParserPrefs ->
  ParserInfo a ->
  Eff es a
customExecParser :: forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, Optparse :> es) =>
ParserPrefs -> ParserInfo a -> Eff es a
customExecParser ParserPrefs
prefs = Optparse (Eff es) a -> Eff es a
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Optparse (Eff es) a -> Eff es a)
-> (ParserInfo a -> Optparse (Eff es) a)
-> ParserInfo a
-> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParserPrefs -> ParserInfo a -> Optparse (Eff es) a
forall a (m :: * -> *). ParserPrefs -> ParserInfo a -> Optparse m a
CustomExecParser ParserPrefs
prefs

-- | Lifted 'OA.handleParseResult'.
--
-- @since 0.1
handleParseResult :: (HasCallStack, Optparse :> es) => ParserResult a -> Eff es a
handleParseResult :: forall (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, Optparse :> es) =>
ParserResult a -> Eff es a
handleParseResult = Optparse (Eff es) a -> Eff es a
forall (e :: (* -> *) -> * -> *) (es :: [(* -> *) -> * -> *]) a.
(HasCallStack, DispatchOf e ~ 'Dynamic, e :> es) =>
e (Eff es) a -> Eff es a
send (Optparse (Eff es) a -> Eff es a)
-> (ParserResult a -> Optparse (Eff es) a)
-> ParserResult a
-> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParserResult a -> Optparse (Eff es) a
forall a (m :: * -> *). ParserResult a -> Optparse m a
HandleParseResult