commander-0.1.0.0: examples/Example1.hs
{-# LANGUAGE DataKinds, ScopedTypeVariables #-}
module Main where
import qualified Data.Map as Map
import Commander.Params (Flag(..), Value(..))
import Commander.Commands (Command(..), commands, command, help, run, evalCommand)
--
-- build up a Command (IO ()) object. The IO () is based
-- on the output of the functions used in the commands.
--
someCommands :: Command (IO ())
someCommands = commands $ do
command "repeat" $ do
help "Repeat a string n times"
run $
\(Value str :: Value "value to repeat" String)
(Flag n :: Flag '["n"] "times to repeat" Int) ->
sequence_ $ replicate n (putStrLn str)
command "calculate" $ do
help "perform calculations"
command "add" $ do
help "add two numbers"
run $
\(Value n1 :: Value "number 1" Int)
(Value n2 :: Value "number 2" Int)
(Flag verbose :: Flag '["v", "verbose"] "verbose mode" Bool) ->
if verbose
then putStrLn $ (show n1) ++ " + " ++ (show n2) ++ " = " ++ (show $ n1 + n2)
else putStrLn (show $ n1 + n2)
command "multiply" $ do
help "multiply two numbers"
run $
\(Value n1 :: Value "number 1" Int)
(Value n2 :: Value "number 2" Int) ->
putStrLn $ (show n1) ++ " x " ++ (show n2) ++ " = " ++ (show $ n1 * n2)
command "login" $ do
help "pretend authentication"
run $
\(Value username :: Value "Username" String)
(Flag mPassword :: Flag '["p", "password"] "Password" (Maybe String)) -> do
pass <- case mPassword of
Just password -> return password
Nothing -> getLine
putStrLn $ "logging in with username=" ++ username ++ " password=" ++ pass
--
-- run an IO () command, printing the error or command output:
--
runCommand :: [String] -> [(String,String)] -> Command (IO ()) -> IO ()
runCommand vals flags cmds = case evalCommand vals (Map.fromList flags) cmds of
Left err -> putStrLn ("Error: " ++ show err)
Right res -> res
--
-- run some commands. Here, we basically pass in strings denoting a path and flags.
-- Commander maps these to output commands if possible, performing whatever type
-- converstion is required to conform to the flags and values these commands expect
-- in a completely safe way.
--
main :: IO ()
main = do
putStrLn "\nRepeat Command:"
runCommand ["repeat", "hello there"] [("n","2")] someCommands
putStrLn "\nAdd numbers:"
runCommand ["calculate", "add", "12", "13"] [] someCommands
putStrLn "\nAdd numbers (verbosely):"
runCommand ["calculate", "add", "12", "13"] [("verbose", "")] someCommands
putStrLn "\nMultiply numbers:"
runCommand ["calculate", "multiply", "12", "13"] [] someCommands
putStrLn "\nPretend Auth (password provided):"
runCommand ["login", "james"] [("p", "lemons")] someCommands
putStrLn "\nPretend Auth (please type a random string):"
runCommand ["login", "james"] [] someCommands