module Options
( Opts(..)
, NextSongFlag(..)
, execParser
, prefs
, showHelpOnEmpty
, optsParser
, optsParserInfo ) where
import Options.Applicative
( (<**>),
auto,
fullDesc,
header,
help,
info,
long,
metavar,
option,
strOption,
flag',
prefs,
progDesc,
short,
showHelpOnEmpty,
value,
execParser,
Parser,
ParserInfo,
infoOption,
hidden,
many,
(<|>) )
import Options.Applicative.Extra ( helperWith )
import Version ( versionStr, progName )
import Data.Kind (Type)
data Opts = Opts
{ Opts -> Integer
optPort :: Integer
, Opts -> String
optHost :: String
, Opts -> String
optPass :: String
, Opts -> NextSongFlag
optNext :: NextSongFlag
, Opts -> * -> *
optVersion :: Type -> Type
}
data NextSongFlag = IncludeNextSong
| OnlyNextSong
| NoNextSong
optsParser :: Parser Opts
optsParser :: Parser Opts
optsParser
= Integer -> String -> String -> NextSongFlag -> (* -> *) -> Opts
Opts
(Integer -> String -> String -> NextSongFlag -> (* -> *) -> Opts)
-> Parser Integer
-> Parser (String -> String -> NextSongFlag -> (* -> *) -> Opts)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Integer
portOptParser
Parser (String -> String -> NextSongFlag -> (* -> *) -> Opts)
-> Parser String
-> Parser (String -> NextSongFlag -> (* -> *) -> Opts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser String
hostOptParser
Parser (String -> NextSongFlag -> (* -> *) -> Opts)
-> Parser String -> Parser (NextSongFlag -> (* -> *) -> Opts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser String
passOptParser
Parser (NextSongFlag -> (* -> *) -> Opts)
-> Parser NextSongFlag -> Parser ((* -> *) -> Opts)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser NextSongFlag
nextSongOptParser
Parser ((* -> *) -> Opts) -> Parser (* -> *) -> Parser Opts
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (* -> *)
forall a. Parser (a -> a)
versionOptParse
where
nextSongOptParser :: Parser NextSongFlag
nextSongOptParser = Parser NextSongFlag
nextSongFlagCountOptParser
Parser NextSongFlag -> Parser NextSongFlag -> Parser NextSongFlag
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser NextSongFlag
nextSongOnlyOptParser
portOptParser :: Parser Integer
portOptParser :: Parser Integer
portOptParser
= ReadM Integer -> Mod OptionFields Integer -> Parser Integer
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Integer
forall a. Read a => ReadM a
auto
(Mod OptionFields Integer -> Parser Integer)
-> Mod OptionFields Integer -> Parser Integer
forall a b. (a -> b) -> a -> b
$ String -> Mod OptionFields Integer
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"port"
Mod OptionFields Integer
-> Mod OptionFields Integer -> Mod OptionFields Integer
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields Integer
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'p'
Mod OptionFields Integer
-> Mod OptionFields Integer -> Mod OptionFields Integer
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Integer
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PORTNUM"
Mod OptionFields Integer
-> Mod OptionFields Integer -> Mod OptionFields Integer
forall a. Semigroup a => a -> a -> a
<> Integer -> Mod OptionFields Integer
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Integer
6600
Mod OptionFields Integer
-> Mod OptionFields Integer -> Mod OptionFields Integer
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields Integer
forall (f :: * -> *) a. String -> Mod f a
help String
"Port number"
hostOptParser :: Parser String
hostOptParser :: Parser String
hostOptParser
= Mod OptionFields String -> Parser String
forall s. IsString s => Mod OptionFields s -> Parser s
strOption
(Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$ String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"ADDRESS"
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"host"
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'h'
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value String
"localhost"
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help String
"Host address"
passOptParser :: Parser String
passOptParser :: Parser String
passOptParser
= ReadM String -> Mod OptionFields String -> Parser String
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM String
forall a. Read a => ReadM a
auto
(Mod OptionFields String -> Parser String)
-> Mod OptionFields String -> Parser String
forall a b. (a -> b) -> a -> b
$ String -> Mod OptionFields String
forall (f :: * -> *) a. HasMetavar f => String -> Mod f a
metavar String
"PASSWORD"
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"password"
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields String
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'P'
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value String
""
Mod OptionFields String
-> Mod OptionFields String -> Mod OptionFields String
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields String
forall (f :: * -> *) a. String -> Mod f a
help String
"Password for connecting (will be sent as plain text)"
nextSongFlagCountOptParser :: Parser NextSongFlag
nextSongFlagCountOptParser :: Parser NextSongFlag
nextSongFlagCountOptParser =
([()] -> NextSongFlag) -> Parser [()] -> Parser NextSongFlag
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> NextSongFlag
intToNextSong (Int -> NextSongFlag) -> ([()] -> Int) -> [()] -> NextSongFlag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [()] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length) (Parser [()] -> Parser NextSongFlag)
-> (Parser () -> Parser [()]) -> Parser () -> Parser NextSongFlag
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser () -> Parser [()]
forall a. Parser a -> Parser [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many
(Parser () -> Parser NextSongFlag)
-> Parser () -> Parser NextSongFlag
forall a b. (a -> b) -> a -> b
$ () -> Mod FlagFields () -> Parser ()
forall a. a -> Mod FlagFields a -> Parser a
flag' ()
(Mod FlagFields () -> Parser ()) -> Mod FlagFields () -> Parser ()
forall a b. (a -> b) -> a -> b
$ Char -> Mod FlagFields ()
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'n'
Mod FlagFields () -> Mod FlagFields () -> Mod FlagFields ()
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields ()
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"next"
Mod FlagFields () -> Mod FlagFields () -> Mod FlagFields ()
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields ()
forall (f :: * -> *) a. String -> Mod f a
help ( [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ String
"If used once (e.g. -n), include next song information in the output.\n"
, String
"If used twice (e.g. -nn) it's an alias for --next-only." ])
nextSongOnlyOptParser :: Parser NextSongFlag
nextSongOnlyOptParser :: Parser NextSongFlag
nextSongOnlyOptParser
= NextSongFlag -> Mod FlagFields NextSongFlag -> Parser NextSongFlag
forall a. a -> Mod FlagFields a -> Parser a
flag' NextSongFlag
OnlyNextSong
( String -> Mod FlagFields NextSongFlag
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"next-only"
Mod FlagFields NextSongFlag
-> Mod FlagFields NextSongFlag -> Mod FlagFields NextSongFlag
forall a. Semigroup a => a -> a -> a
<> String -> Mod FlagFields NextSongFlag
forall (f :: * -> *) a. String -> Mod f a
help String
"Only print next song information." )
intToNextSong :: Int -> NextSongFlag
intToNextSong :: Int -> NextSongFlag
intToNextSong Int
count
| Int
count Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = NextSongFlag
IncludeNextSong
| Int
count Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 = NextSongFlag
OnlyNextSong
| Bool
otherwise = NextSongFlag
NoNextSong
versionOptParse :: Parser (a -> a)
versionOptParse :: forall a. Parser (a -> a)
versionOptParse =
String -> Mod OptionFields (a -> a) -> Parser (a -> a)
forall a. String -> Mod OptionFields (a -> a) -> Parser (a -> a)
infoOption String
versionStr
(Mod OptionFields (a -> a) -> Parser (a -> a))
-> Mod OptionFields (a -> a) -> Parser (a -> a)
forall a b. (a -> b) -> a -> b
$ String -> Mod OptionFields (a -> a)
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"version"
Mod OptionFields (a -> a)
-> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a)
forall a. Semigroup a => a -> a -> a
<> Char -> Mod OptionFields (a -> a)
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'V'
Mod OptionFields (a -> a)
-> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a)
forall a. Semigroup a => a -> a -> a
<> String -> Mod OptionFields (a -> a)
forall (f :: * -> *) a. String -> Mod f a
help String
"Display the version number"
optsParserInfo :: ParserInfo Opts
optsParserInfo :: ParserInfo Opts
optsParserInfo = Parser Opts -> InfoMod Opts -> ParserInfo Opts
forall a. Parser a -> InfoMod a -> ParserInfo a
info (Parser Opts
optsParser Parser Opts -> Parser (Opts -> Opts) -> Parser Opts
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> Parser (Opts -> Opts)
forall a. Parser (a -> a)
helper')
(InfoMod Opts -> ParserInfo Opts)
-> InfoMod Opts -> ParserInfo Opts
forall a b. (a -> b) -> a -> b
$ InfoMod Opts
forall a. InfoMod a
fullDesc
InfoMod Opts -> InfoMod Opts -> InfoMod Opts
forall a. Semigroup a => a -> a -> a
<> String -> InfoMod Opts
forall a. String -> InfoMod a
progDesc String
"Print currently playing song information as JSON"
InfoMod Opts -> InfoMod Opts -> InfoMod Opts
forall a. Semigroup a => a -> a -> a
<> String -> InfoMod Opts
forall a. String -> InfoMod a
header (String
progName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" - " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Current MPD song information as JSON")
helper' :: Parser (a -> a)
helper' :: forall a. Parser (a -> a)
helper' = Mod OptionFields (a -> a) -> Parser (a -> a)
forall a. Mod OptionFields (a -> a) -> Parser (a -> a)
helperWith
(Mod OptionFields (a -> a) -> Parser (a -> a))
-> Mod OptionFields (a -> a) -> Parser (a -> a)
forall a b. (a -> b) -> a -> b
$ String -> Mod OptionFields (a -> a)
forall (f :: * -> *) a. HasName f => String -> Mod f a
long String
"help"
Mod OptionFields (a -> a)
-> Mod OptionFields (a -> a) -> Mod OptionFields (a -> a)
forall a. Semigroup a => a -> a -> a
<> Mod OptionFields (a -> a)
forall (f :: * -> *) a. Mod f a
hidden