{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE Rank2Types                 #-}

-- | exports from "Yi.Config.Simple" which are useful to \"core yi\" rather than just config files.
module Yi.Config.Simple.Types
 where

import Lens.Micro.Platform (Lens')
import Control.Monad.Base  (MonadBase)
import Control.Monad.State (MonadState, StateT)
import Yi.Config           (Config, configVariable)
import Yi.Types            (YiConfigVariable)

-- | The configuration monad. Run it with 'configMain'.
newtype ConfigM a = ConfigM {
    ConfigM a -> StateT Config IO a
runConfigM :: StateT Config IO a
  } deriving (Applicative ConfigM
a -> ConfigM a
Applicative ConfigM
-> (forall a b. ConfigM a -> (a -> ConfigM b) -> ConfigM b)
-> (forall a b. ConfigM a -> ConfigM b -> ConfigM b)
-> (forall a. a -> ConfigM a)
-> Monad ConfigM
ConfigM a -> (a -> ConfigM b) -> ConfigM b
ConfigM a -> ConfigM b -> ConfigM b
forall a. a -> ConfigM a
forall a b. ConfigM a -> ConfigM b -> ConfigM b
forall a b. ConfigM a -> (a -> ConfigM b) -> ConfigM b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> ConfigM a
$creturn :: forall a. a -> ConfigM a
>> :: ConfigM a -> ConfigM b -> ConfigM b
$c>> :: forall a b. ConfigM a -> ConfigM b -> ConfigM b
>>= :: ConfigM a -> (a -> ConfigM b) -> ConfigM b
$c>>= :: forall a b. ConfigM a -> (a -> ConfigM b) -> ConfigM b
$cp1Monad :: Applicative ConfigM
Monad, a -> ConfigM b -> ConfigM a
(a -> b) -> ConfigM a -> ConfigM b
(forall a b. (a -> b) -> ConfigM a -> ConfigM b)
-> (forall a b. a -> ConfigM b -> ConfigM a) -> Functor ConfigM
forall a b. a -> ConfigM b -> ConfigM a
forall a b. (a -> b) -> ConfigM a -> ConfigM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ConfigM b -> ConfigM a
$c<$ :: forall a b. a -> ConfigM b -> ConfigM a
fmap :: (a -> b) -> ConfigM a -> ConfigM b
$cfmap :: forall a b. (a -> b) -> ConfigM a -> ConfigM b
Functor, Functor ConfigM
a -> ConfigM a
Functor ConfigM
-> (forall a. a -> ConfigM a)
-> (forall a b. ConfigM (a -> b) -> ConfigM a -> ConfigM b)
-> (forall a b c.
    (a -> b -> c) -> ConfigM a -> ConfigM b -> ConfigM c)
-> (forall a b. ConfigM a -> ConfigM b -> ConfigM b)
-> (forall a b. ConfigM a -> ConfigM b -> ConfigM a)
-> Applicative ConfigM
ConfigM a -> ConfigM b -> ConfigM b
ConfigM a -> ConfigM b -> ConfigM a
ConfigM (a -> b) -> ConfigM a -> ConfigM b
(a -> b -> c) -> ConfigM a -> ConfigM b -> ConfigM c
forall a. a -> ConfigM a
forall a b. ConfigM a -> ConfigM b -> ConfigM a
forall a b. ConfigM a -> ConfigM b -> ConfigM b
forall a b. ConfigM (a -> b) -> ConfigM a -> ConfigM b
forall a b c. (a -> b -> c) -> ConfigM a -> ConfigM b -> ConfigM c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: ConfigM a -> ConfigM b -> ConfigM a
$c<* :: forall a b. ConfigM a -> ConfigM b -> ConfigM a
*> :: ConfigM a -> ConfigM b -> ConfigM b
$c*> :: forall a b. ConfigM a -> ConfigM b -> ConfigM b
liftA2 :: (a -> b -> c) -> ConfigM a -> ConfigM b -> ConfigM c
$cliftA2 :: forall a b c. (a -> b -> c) -> ConfigM a -> ConfigM b -> ConfigM c
<*> :: ConfigM (a -> b) -> ConfigM a -> ConfigM b
$c<*> :: forall a b. ConfigM (a -> b) -> ConfigM a -> ConfigM b
pure :: a -> ConfigM a
$cpure :: forall a. a -> ConfigM a
$cp1Applicative :: Functor ConfigM
Applicative, MonadState Config, MonadBase IO)

-- | Fields that can be modified with all lens machinery.
type Field a = Lens' Config a

{- | Accessor for any 'YiConfigVariable', to be used by modules defining
'YiConfigVariable's. Such modules should provide a custom-named field.
For instance, take the following hypothetical 'YiConfigVariable':

@newtype UserName = UserName { unUserName :: String }
  deriving(Typeable, Binary, Default)
instance YiConfigVariable UserName

$(nameDeriveAccessors ''UserName (\n -> Just (n ++ \"A\")))

userName :: 'Field' 'String'
userName = unUserNameA '.' 'customVariable'@

Here, the hypothetical library would provide the field @userName@ to be used in preference to @customVariable@.
-}
customVariable :: YiConfigVariable a => Field a
customVariable :: Field a
customVariable = (a -> f a) -> Config -> f Config
forall a. YiConfigVariable a => Lens Config Config a a
configVariable