{-# LANGUAGE RecordWildCards #-} import System.IO import Control.Monad (when) import Paths_alea (getDataFileName) import Alea.Diceware import Alea.Random data ProgArgs = ProgArgs { interactive :: Bool , dictionary :: FilePath , phraseLength :: Int , phrases :: Int } deriving (Show) parser :: IO (ParserSpec ProgArgs) parser = path >>= \path -> return $ ProgArgs `parsedBy` boolFlag "interactive" `Descr` "Manually insert numbers" `andBy` optFlag path "dictionary" `Descr` "Specify dictionary file path" `andBy` optFlag 6 "lenght" `Descr` "Number of words in a passphrase" `andBy` optFlag 1 "phrases" `Descr` "Number of passphrases to generate" interface :: IO (CmdLnInterface ProgArgs) interface = (`setAppDescr` "A diceware passphrase generator") <$> (`setAppEpilog` "Alea iacta est.") <$> (mkApp =<< parser) main :: IO () main = getProgArgs >>= defaults >>= exec -- Main function exec :: ProgArgs -> IO () exec args@ProgArgs{..} = if interactive then interact (unlines . map dice . lines) else do randWords dictSize phraseLength >>= putStrLn . unwords . map dice' when (phrases > 1) $ exec args {phrases = phrases - 1} where (dict, dictSize) = (parseDiceware dictionary, length dict) dice n = readDiceware dict (read n :: Int) dice' n = readDiceware' dict n