From b3bb13eb620d293c9b607d1e3b68e3c81d12f10f Mon Sep 17 00:00:00 2001 From: rnhmjoj Date: Thu, 5 May 2016 16:24:03 +0200 Subject: [PATCH] Drop argparser --- alea.cabal | 3 ++- src/Main.hs | 68 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/alea.cabal b/alea.cabal index 42a525c..e2b31b3 100644 --- a/alea.cabal +++ b/alea.cabal @@ -29,5 +29,6 @@ executable alea default-language: Haskell2010 other-modules: Alea.Diceware other-extensions: DeriveDataTypeable, RecordWildCards - build-depends: base >=4.8 && < 5.0, random, text, argparser + build-depends: base >=4.8 && < 5.0, random, text, + optparse-applicative ghc-options: -O2 diff --git a/src/Main.hs b/src/Main.hs index f360e14..8d8a959 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -2,7 +2,7 @@ import Control.Monad (when, forever) import Data.Text (unpack) -import System.Console.ArgParser +import Options.Applicative import Alea.Diceware import Paths_alea (getDataFileName) @@ -13,55 +13,67 @@ import qualified Data.Text.IO as I -- * Command line interface description -- | Program arguments record -data ProgArgs = ProgArgs +data Options = Options { interactive :: Bool - , dictionary :: FilePath + , dictionary :: Maybe FilePath , phraseLength :: Int , phrases :: Int - } deriving (Show) + } --- | Default dictionary path -defaultPath :: IO FilePath -defaultPath = getDataFileName "dict/diceware" +-- | Argument parser +options :: Parser Options +options = Options + <$> switch + ( long "interactive" + <> help "Manually insert numbers from a dice" ) + <*> optional (option auto + ( long "dictionary" + <> metavar "FILEPATH" + <> help "Specify dictionary filepath" )) + <*> option auto + ( long "length" + <> value 6 + <> metavar "N" + <> help "Number of words in a passphrase") + <*> option auto + ( long "phrases" + <> value 1 + <> metavar "M" + <> help "Number of passphrases to generate" ) + +-- | Program description +description :: ParserInfo Options +description = info (helper <*> options) + ( fullDesc + <> progDesc "A diceware passphrase generator" + <> footer "Alea iacta est." ) --- | Arguments descriptions -argParser :: FilePath -> ParserSpec ProgArgs -argParser path = ProgArgs - `parsedBy` boolFlag "interactive" `Descr` "Manually insert numbers" - `andBy` optFlag path "dictionary" `Descr` "Specify dictionary filepath" - `andBy` optFlag 6 "lenght" `Descr` "Number of words in a passphrase" - `andBy` optFlag 1 "phrases" `Descr` "Number of passphrases to generate" - - --- | CLI interface -interface :: FilePath -> IO (CmdLnInterface ProgArgs) -interface path = - (`setAppDescr` "A diceware passphrase generator") <$> - (`setAppEpilog` "Alea iacta est.") <$> - mkApp (argParser path) -- * Program -- | Main function main :: IO () -main = defaultPath >>= interface >>= (`runApp` diceware) +main = execParser description >>= diceware -- | Actual application -diceware :: ProgArgs -> IO () -diceware args@ProgArgs{..} = do - dict <- fmap parseDiceware (I.readFile dictionary) +diceware :: Options -> IO () +diceware opts@Options{..} = do + path <- case dictionary of + Nothing -> getDataFileName "dict/diceware" + Just x -> return x + dict <- parseDiceware <$> I.readFile path let size = length dict-1 dice = readDiceware dict . read . unpack dice' = readDiceware' dict if interactive - then forever (fmap dice I.getLine >>= I.putStrLn) + then forever (dice <$> I.getLine >>= I.putStrLn) else do indices <- randIndices size phraseLength I.putStrLn $ T.unwords (map dice' indices) when (phrases > 1) $ - diceware args {phrases = phrases - 1} + diceware opts {phrases = phrases - 1}