General rewrite with Data.Text

This commit is contained in:
rnhmjoj 2016-04-28 18:08:48 +02:00
parent 245566e059
commit 88864d4998
No known key found for this signature in database
GPG Key ID: 362BB82B7E496B7C
2 changed files with 67 additions and 55 deletions

67
src/Main.hs Normal file
View File

@ -0,0 +1,67 @@
{-# LANGUAGE RecordWildCards #-}
import Control.Monad (when, forever)
import Data.Text (unpack)
import System.Console.ArgParser
import Alea.Diceware
import Paths_alea (getDataFileName)
import qualified Data.Text as T
import qualified Data.Text.IO as I
-- * Command line interface description
-- | Program arguments record
data ProgArgs = ProgArgs
{ interactive :: Bool
, dictionary :: FilePath
, phraseLength :: Int
, phrases :: Int
} deriving (Show)
-- | Default dictionary path
defaultPath :: IO FilePath
defaultPath = getDataFileName "dict/diceware"
-- | 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)
-- | Actual application
diceware :: ProgArgs -> IO ()
diceware args@ProgArgs{..} = do
dict <- fmap parseDiceware (I.readFile dictionary)
let size = length dict-1
dice = readDiceware dict . read . unpack
dice' = readDiceware' dict
if interactive
then forever (fmap dice I.getLine >>= I.putStrLn)
else do
indices <- genIndex size phraseLength
I.putStrLn $ T.unwords (map dice' indices)
when (phrases > 1) $
diceware args {phrases = phrases - 1}

View File

@ -1,55 +0,0 @@
{-# LANGUAGE RecordWildCards #-}
import System.IO
import System.Console.ArgParser
import Control.Monad
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 -> 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")
<$> path
interface :: IO (CmdLnInterface ProgArgs)
interface =
(`setAppDescr` "A diceware passphrase generator") <$>
(`setAppEpilog` "Alea iacta est.") <$>
(mkApp =<< parser)
main :: IO ()
main = interface >>= flip runApp (readDict >=> exec)
-- Default path of the dictionary
path :: IO FilePath
path = getDataFileName "dict/diceware"
-- Read dictionary file
readDict :: ProgArgs -> IO ProgArgs
readDict args@ProgArgs{..} =
(\x -> args {dictionary = x}) <$> readFile dictionary
-- 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