packages feed

axel-0.0.11: src/Axel/Eff/Console.hs

{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}

module Axel.Eff.Console where

import Axel.Prelude

import qualified Data.Text as T
import qualified Data.Text.IO as T

import qualified Polysemy as Sem

import qualified System.Console.ANSI as ANSI (getTerminalSize)

data Console m a where
  GetTerminalSize :: Console m (Maybe (Int, Int))
  PutStr :: Text -> Console m ()

Sem.makeSem ''Console

runConsole ::
     (Sem.Member (Sem.Embed IO) effs)
  => Sem.Sem (Console ': effs) a
  -> Sem.Sem effs a
runConsole =
  Sem.interpret $ \case
    GetTerminalSize -> Sem.embed ANSI.getTerminalSize
    PutStr str -> Sem.embed $ T.putStr str

putStrLn :: (Sem.Member Console effs) => Text -> Sem.Sem effs ()
putStrLn = putStr . (<> "\n")

putHorizontalLine :: (Sem.Member Console effs) => Sem.Sem effs ()
putHorizontalLine = do
  maybeTerminalSize <- getTerminalSize
  case maybeTerminalSize of
    Just (_, width) -> putStrLn $ T.replicate width "\x2500"
    Nothing -> pure ()