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

import RIO

import TonaParser (Parser, withConfig)

{-| Main function.
 -}
run :: HasParser env => RIO env () -> IO ()
run :: RIO env () -> IO ()
run RIO env ()
action = do
  Parser env -> (env -> IO ()) -> IO ()
forall a. Parser a -> (a -> IO ()) -> IO ()
withConfig Parser env
forall a. HasParser a => Parser a
parser ((env -> IO ()) -> IO ()) -> (env -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \env
env ->
    env -> RIO env () -> IO ()
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 :: (IO a -> IO b) -> RIO env a -> RIO env b
liftIOMap IO a -> IO b
f RIO env a
rio =
  ReaderT env IO b -> RIO env b
forall env a. ReaderT env IO a -> RIO env a
RIO (ReaderT env IO b -> RIO env b) -> ReaderT env IO b -> RIO env b
forall a b. (a -> b) -> a -> b
$ (env -> IO b) -> ReaderT env IO b
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((env -> IO b) -> ReaderT env IO b)
-> (env -> IO b) -> ReaderT env IO b
forall a b. (a -> b) -> a -> b
$ \env
env -> IO a -> IO b
f (ReaderT env IO a -> env -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (RIO env a -> ReaderT env IO a
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 :: ((a -> IO b) -> IO c) -> (a -> RIO env b) -> RIO env c
liftIOCont (a -> IO b) -> IO c
f a -> RIO env b
action =
  ReaderT env IO c -> RIO env c
forall env a. ReaderT env IO a -> RIO env a
RIO (ReaderT env IO c -> RIO env c) -> ReaderT env IO c -> RIO env c
forall a b. (a -> b) -> a -> b
$ (env -> IO c) -> ReaderT env IO c
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((env -> IO c) -> ReaderT env IO c)
-> (env -> IO c) -> ReaderT env IO c
forall a b. (a -> b) -> a -> b
$ \env
env -> (a -> IO b) -> IO c
f (\a
a -> ReaderT env IO b -> env -> IO b
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (RIO env b -> ReaderT env IO b
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