module Tonatona
  ( run
  , liftIOMap
  , liftIOCont
  , HasParser(..)
  , HasConfig(..)
  ) where

import RIO

import TonaParser (Parser, withConfig)

{-| Main function.
 -}
run :: HasParser env => RIO env () -> IO ()
run :: forall env. HasParser env => RIO env () -> IO ()
run RIO env ()
action = do
  forall a. Parser a -> (a -> IO ()) -> IO ()
withConfig forall a. HasParser a => Parser a
parser forall a b. (a -> b) -> a -> b
$ \env
env ->
    forall (m :: * -> *) env a. MonadIO m => env -> RIO env a -> m a
runRIO env
env RIO env ()
action

{-| Lift IO map function into RIO.
 -}
liftIOMap :: (IO a -> IO b) -> RIO env a -> RIO env b
liftIOMap :: forall a b env. (IO a -> IO b) -> RIO env a -> RIO env b
liftIOMap IO a -> IO b
f RIO env a
rio =
  forall env a. ReaderT env IO a -> RIO env a
RIO forall a b. (a -> b) -> a -> b
$ forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ \env
env -> IO a -> IO b
f (forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall env a. RIO env a -> ReaderT env IO a
unRIO RIO env a
rio) env
env)

{-| Lift Continuation-passing style IO function into RIO.
 -}
liftIOCont :: ((a -> IO b) -> IO c) -> (a -> RIO env b) -> RIO env c
liftIOCont :: forall a b c env.
((a -> IO b) -> IO c) -> (a -> RIO env b) -> RIO env c
liftIOCont (a -> IO b) -> IO c
f a -> RIO env b
action =
  forall env a. ReaderT env IO a -> RIO env a
RIO forall a b. (a -> b) -> a -> b
$ forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ \env
env -> (a -> IO b) -> IO c
f (\a
a -> forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall env a. RIO env a -> ReaderT env IO a
unRIO (a -> RIO env b
action a
a)) env
env)

class HasParser a where
  parser :: Parser a

class HasConfig env config where
  config :: env -> config