{-# OPTIONS_GHC -Wall #-}
module Debian.Debianize.Monad
    ( CabalInfo
    , CabalT
    , runCabalT
    , evalCabalT
    , execCabalT
    , CabalM
    , runCabalM
    , evalCabalM
    , execCabalM

    -- * modify cabal to debian package version map
    -- , mapCabal
    -- , splitCabal

    , DebianT
    , evalDebianT
    , evalDebian
    , execDebianT
    , liftCabal

    , ifM
    , whenM
    , unlessM
    ) where

import Control.Lens
import Control.Monad.State (evalState, evalStateT, execState, execStateT, runState, State, StateT(runStateT))
import Debian.Debianize.DebInfo (DebInfo)
import Debian.Debianize.CabalInfo (CabalInfo, debInfo)
import Debian.Orphans ()
import Prelude hiding (init, log, unlines)

type CabalT m = StateT CabalInfo m -- Better name - CabalT?
type CabalM = State CabalInfo

execCabalT :: Monad m => CabalT m a -> CabalInfo -> m CabalInfo
execCabalT :: CabalT m a -> CabalInfo -> m CabalInfo
execCabalT CabalT m a
action CabalInfo
atoms = CabalT m a -> CabalInfo -> m CabalInfo
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT CabalT m a
action CabalInfo
atoms

evalCabalT :: Monad m => CabalT m a -> CabalInfo -> m a
evalCabalT :: CabalT m a -> CabalInfo -> m a
evalCabalT CabalT m a
action CabalInfo
atoms = CabalT m a -> CabalInfo -> m a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT CabalT m a
action CabalInfo
atoms

runCabalT :: CabalT m a -> CabalInfo -> m (a, CabalInfo)
runCabalT :: CabalT m a -> CabalInfo -> m (a, CabalInfo)
runCabalT CabalT m a
action CabalInfo
atoms = CabalT m a -> CabalInfo -> m (a, CabalInfo)
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT CabalT m a
action CabalInfo
atoms

execCabalM :: CabalM a -> CabalInfo -> CabalInfo
execCabalM :: CabalM a -> CabalInfo -> CabalInfo
execCabalM CabalM a
action CabalInfo
atoms = CabalM a -> CabalInfo -> CabalInfo
forall s a. State s a -> s -> s
execState CabalM a
action CabalInfo
atoms

evalCabalM :: CabalM a -> CabalInfo -> a
evalCabalM :: CabalM a -> CabalInfo -> a
evalCabalM CabalM a
action CabalInfo
atoms = CabalM a -> CabalInfo -> a
forall s a. State s a -> s -> a
evalState CabalM a
action CabalInfo
atoms

runCabalM :: CabalM a -> CabalInfo -> (a, CabalInfo)
runCabalM :: CabalM a -> CabalInfo -> (a, CabalInfo)
runCabalM CabalM a
action CabalInfo
atoms = CabalM a -> CabalInfo -> (a, CabalInfo)
forall s a. State s a -> s -> (a, s)
runState CabalM a
action CabalInfo
atoms

type DebianT m = StateT DebInfo m

evalDebianT :: Monad m => DebianT m a -> DebInfo -> m a
evalDebianT :: DebianT m a -> DebInfo -> m a
evalDebianT = DebianT m a -> DebInfo -> m a
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT

evalDebian :: DebianT Identity a -> DebInfo -> a
evalDebian :: DebianT Identity a -> DebInfo -> a
evalDebian = DebianT Identity a -> DebInfo -> a
forall s a. State s a -> s -> a
evalState

execDebianT :: Monad m => DebianT m () -> DebInfo -> m DebInfo
execDebianT :: DebianT m () -> DebInfo -> m DebInfo
execDebianT = DebianT m () -> DebInfo -> m DebInfo
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT

liftCabal :: Monad m => StateT DebInfo m a -> StateT CabalInfo m a
liftCabal :: StateT DebInfo m a -> StateT CabalInfo m a
liftCabal = LensLike' (Zoomed (StateT DebInfo m) a) CabalInfo DebInfo
-> StateT DebInfo m a -> StateT CabalInfo m a
forall (m :: * -> *) (n :: * -> *) s t c.
Zoom m n s t =>
LensLike' (Zoomed m c) t s -> m c -> n c
zoom LensLike' (Zoomed (StateT DebInfo m) a) CabalInfo DebInfo
Lens' CabalInfo DebInfo
debInfo

ifM :: Monad m => m Bool -> m a -> m a -> m a
ifM :: m Bool -> m a -> m a -> m a
ifM m Bool
m m a
t m a
f = m Bool
m m Bool -> (Bool -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Bool
b -> if Bool
b then m a
t else m a
f

whenM :: Monad m => m Bool -> m () -> m ()
whenM :: m Bool -> m () -> m ()
whenM m Bool
m m ()
r = m Bool
m m Bool -> (Bool -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Bool
b -> if Bool
b then m ()
r else () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

unlessM :: Monad m => m Bool -> m () -> m ()
unlessM :: m Bool -> m () -> m ()
unlessM m Bool
m m ()
r = m Bool
m m Bool -> (Bool -> m ()) -> m ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ Bool
b -> if Bool
b then () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return () else m ()
r