{-# LANGUAGE OverloadedStrings #-}
module Wordlist.Args
( Args (..), getArgs, argsNumber, argsDelimiter
, argsP
, defaultNumber, defaultDelimiter
, numberP, delimiterP
) where
import Control.Applicative (optional)
import Data.Maybe (fromMaybe)
import Data.Text (Text)
import Options.Applicative.Extra (execParser, helper)
import Options.Applicative.Types (Parser)
import qualified Data.Text as Text
import qualified Options.Applicative.Builder as Opt
data Args = Args
{ Args -> Maybe Int
argsNumberMaybe :: Maybe Int
, Args -> Maybe Text
argsDelimiterMaybe :: Maybe Text
}
defaultNumber :: Int
defaultNumber :: Int
defaultNumber = Int
4
defaultDelimiter :: Text
defaultDelimiter :: Text
defaultDelimiter = Text
" "
numberP :: Parser (Maybe Int)
numberP :: Parser (Maybe Int)
numberP =
Parser Int -> Parser (Maybe Int)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Int -> Parser (Maybe Int))
-> Parser Int -> Parser (Maybe Int)
forall a b. (a -> b) -> a -> b
$ ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
Opt.option ReadM Int
forall a. Read a => ReadM a
Opt.auto (Mod OptionFields Int -> Parser Int)
-> Mod OptionFields Int -> Parser Int
forall a b. (a -> b) -> a -> b
$
String -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => String -> Mod f a
Opt.long String
"number" Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => Char -> Mod f a
Opt.short Char
'n' Mod OptionFields Int
-> Mod OptionFields Int -> Mod OptionFields Int
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Int
forall (f :: * -> *) a. String -> Mod f a
Opt.help String
help
where
help :: String
help = String
"Number of words (default: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>
Int -> String
forall a. Show a => a -> String
show Int
defaultNumber String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
")"
delimiterP :: Parser (Maybe Text)
delimiterP :: Parser (Maybe Text)
delimiterP =
Parser Text -> Parser (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser (Maybe Text))
-> Parser Text -> Parser (Maybe Text)
forall a b. (a -> b) -> a -> b
$ ReadM Text -> Mod OptionFields Text -> Parser Text
forall a. ReadM a -> Mod OptionFields a -> Parser a
Opt.option ((String -> Text) -> ReadM String -> ReadM Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
Text.pack ReadM String
forall s. IsString s => ReadM s
Opt.str) (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$
String -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => String -> Mod f a
Opt.long String
"delimiter" Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => Char -> Mod f a
Opt.short Char
'd' Mod OptionFields Text
-> Mod OptionFields Text -> Mod OptionFields Text
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Text
forall (f :: * -> *) a. String -> Mod f a
Opt.help String
help
where
help :: String
help = String
"Delimiter between words (default: space)"
argsP :: Parser Args
argsP :: Parser Args
argsP =
Maybe Int -> Maybe Text -> Args
Args (Maybe Int -> Maybe Text -> Args)
-> Parser (Maybe Int) -> Parser (Maybe Text -> Args)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Maybe Int)
numberP Parser (Maybe Text -> Args) -> Parser (Maybe Text) -> Parser Args
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe Text)
delimiterP
parserInfo :: Opt.InfoMod a
parserInfo :: InfoMod a
parserInfo =
String -> InfoMod a
forall a. String -> InfoMod a
Opt.header
String
"Generates random English words. Useful for password generation."
getArgs :: IO Args
getArgs :: IO Args
getArgs =
ParserInfo Args -> IO Args
forall a. ParserInfo a -> IO a
execParser (ParserInfo Args -> IO Args) -> ParserInfo Args -> IO Args
forall a b. (a -> b) -> a -> b
$ Parser Args -> InfoMod Args -> ParserInfo Args
forall a. Parser a -> InfoMod a -> ParserInfo a
Opt.info (Parser (Args -> Args)
forall a. Parser (a -> a)
helper Parser (Args -> Args) -> Parser Args -> Parser Args
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Args
argsP) InfoMod Args
forall a. InfoMod a
parserInfo
argsNumber :: Args -> Int
argsNumber :: Args -> Int
argsNumber =
Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
defaultNumber (Maybe Int -> Int) -> (Args -> Maybe Int) -> Args -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Args -> Maybe Int
argsNumberMaybe
argsDelimiter :: Args -> Text
argsDelimiter :: Args -> Text
argsDelimiter =
Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
defaultDelimiter (Maybe Text -> Text) -> (Args -> Maybe Text) -> Args -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Args -> Maybe Text
argsDelimiterMaybe