{-# OPTIONS_HADDOCK hide #-}

-- |
--
-- Copyright:
--   This file is part of the package byline. It is subject to the
--   license terms in the LICENSE file found in the top-level
--   directory of this distribution and at:
--
--     https://github.com/pjones/byline
--
--   No part of this package, including this file, may be copied,
--   modified, propagated, or distributed except according to the
--   terms contained in the LICENSE file.
--
-- License: BSD-2-Clause
module Byline.Internal.Prim
  ( PrimF (..),
    say,
    sayLn,
    askLn,
    askChar,
    askPassword,
    pushCompFunc,
    popCompFunc,
  )
where

import Byline.Internal.Completion (CompletionFunc)
import Byline.Internal.Stylized (Stylized, text)
import Control.Monad.Trans.Free.Church (MonadFree)
import qualified Control.Monad.Trans.Free.Church as Free

-- | Primitive operations as a free monad.
--
-- @since 1.0.0.0
data PrimF f
  = Say (Stylized Text) f
  | AskLn (Stylized Text) (Maybe Text) (Text -> f)
  | AskChar (Stylized Text) (Char -> f)
  | AskPassword (Stylized Text) (Maybe Char) (Text -> f)
  | PushCompFunc (CompletionFunc IO) f
  | PopCompFunc f
  deriving (forall a b. a -> PrimF b -> PrimF a
forall a b. (a -> b) -> PrimF a -> PrimF b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> PrimF b -> PrimF a
$c<$ :: forall a b. a -> PrimF b -> PrimF a
fmap :: forall a b. (a -> b) -> PrimF a -> PrimF b
$cfmap :: forall a b. (a -> b) -> PrimF a -> PrimF b
Functor)

-- | Smart constructor.
--
-- @since 1.0.0.0
say :: MonadFree PrimF m => Stylized Text -> m ()
say :: forall (m :: * -> *). MonadFree PrimF m => Stylized Text -> m ()
say = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
Free.liftF forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall f. Stylized Text -> f -> PrimF f
`Say` ())

-- | Smart constructor.
--
-- @since 1.0.0.0
sayLn :: MonadFree PrimF m => Stylized Text -> m ()
sayLn :: forall (m :: * -> *). MonadFree PrimF m => Stylized Text -> m ()
sayLn Stylized Text
message = forall (m :: * -> *). MonadFree PrimF m => Stylized Text -> m ()
say (Stylized Text
message forall a. Semigroup a => a -> a -> a
<> Text -> Stylized Text
text Text
"\n")

-- | Smart constructor.
--
-- @since 1.0.0.0
askLn :: MonadFree PrimF m => Stylized Text -> Maybe Text -> m Text
askLn :: forall (m :: * -> *).
MonadFree PrimF m =>
Stylized Text -> Maybe Text -> m Text
askLn Stylized Text
prompt Maybe Text
def = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
Free.liftF (forall f. Stylized Text -> Maybe Text -> (Text -> f) -> PrimF f
AskLn Stylized Text
prompt Maybe Text
def forall a. a -> a
id)

-- | Smart constructor.
--
-- @since 1.0.0.0
askChar :: MonadFree PrimF m => Stylized Text -> m Char
askChar :: forall (m :: * -> *). MonadFree PrimF m => Stylized Text -> m Char
askChar = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
Free.liftF forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall f. Stylized Text -> (Char -> f) -> PrimF f
`AskChar` forall a. a -> a
id)

-- | Smart constructor.
--
-- @since 1.0.0.0
askPassword :: MonadFree PrimF m => Stylized Text -> Maybe Char -> m Text
askPassword :: forall (m :: * -> *).
MonadFree PrimF m =>
Stylized Text -> Maybe Char -> m Text
askPassword Stylized Text
prompt Maybe Char
mask = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
Free.liftF (forall f. Stylized Text -> Maybe Char -> (Text -> f) -> PrimF f
AskPassword Stylized Text
prompt Maybe Char
mask forall a. a -> a
id)

-- | Smart constructor.
--
-- @since 1.0.0.0
pushCompFunc :: MonadFree PrimF m => CompletionFunc IO -> m ()
pushCompFunc :: forall (m :: * -> *).
MonadFree PrimF m =>
CompletionFunc IO -> m ()
pushCompFunc = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
Free.liftF forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall f. CompletionFunc IO -> f -> PrimF f
`PushCompFunc` ())

-- | Smart constructor.
--
-- @since 1.0.0.0
popCompFunc :: MonadFree PrimF m => m ()
popCompFunc :: forall (m :: * -> *). MonadFree PrimF m => m ()
popCompFunc = forall (f :: * -> *) (m :: * -> *) a.
(Functor f, MonadFree f m) =>
f a -> m a
Free.liftF (forall f. f -> PrimF f
PopCompFunc ())