credentials-cli-0.0.2: src/Credentials/CLI/IO.hs
{-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
-- |
-- Module : Credentials.CLI.IO
-- Copyright : (c) 2015-2016 Brendan Hay
-- License : Mozilla Public License, v. 2.0.
-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
-- Stability : provisional
-- Portability : non-portable (GHC extensions)
--
module Credentials.CLI.IO where
import Control.Arrow
import Control.Monad.Reader
import Credentials.CLI.Format
import Credentials.CLI.Types
import Data.Aeson (ToJSON (..))
import Data.Aeson.Encode
import Data.Aeson.Encode.Pretty
import Data.ByteString.Builder (Builder, hPutBuilder, stringUtf8)
import Data.Char (isSpace, toLower)
import Data.Functor.Identity (runIdentity)
import Data.Monoid
import Network.AWS.Data
import Options.Applicative.Help.Pretty
import System.Exit
import System.IO
import qualified Data.ByteString.Builder as Build
default (Builder)
data Agree
= Yes
| No
| What String
quit :: ToLog a => Int -> a -> IO ()
quit n m = err m >> exitWith (ExitFailure n)
err :: (MonadIO m, ToLog a) => a -> m ()
err x = liftIO $ Build.hPutBuilder stderr ("Error!:\n " <> build x <> "\n")
says :: ToLog a => a -> App ()
says x = say (build x <> "\n")
say :: ToLog a => a -> App ()
say x = do
f <- asks format
when (f == Print) $
liftIO $ hPutBuilder stderr (build x)
emit :: Result -> App ()
emit r = do
(f, s) <- asks (format &&& store)
let e = Emit (runIdentity s) r
liftIO . hPutBuilder stdout $
case f of
Pretty -> build (encodePretty e) <> "\n"
JSON -> encodeToBuilder (toJSON e)
Echo -> build r
Print -> stringUtf8
(displayS (renderPretty 0.4 80 (pretty e)) "") <> "\n"
prompt :: Force -> App () -> App ()
prompt NoPrompt io = says "Running ..." >> io
prompt Prompt io = do
say " -> Proceed? [y/n]: "
a <- agree
case a of
Yes -> says "Running ..." >> io
No -> says "Cancelling ..."
What w -> says $ build w <> ", what? Cancelling ..."
agree :: App Agree
agree = do
r <- map toLower . filter (not . isSpace) <$> liftIO getLine
return $! case r of
"yes" -> Yes
"y" -> Yes
"no" -> No
"n" -> No
"" -> No
x -> What x