Instantly share code, notes, and snippets.

Embed
What would you like to do?
import Options.Applicative
data Options = Options {
optTimeout :: Maybe Int,
optCommand :: Command }
deriving Show
data Command
-- domains
= ListDomains (Maybe Int)
| CreateDomain String
| GetDomain String
-- zones
| ListZones (Maybe Int)
| GetZone String
deriving Show
main :: IO ()
main = customExecParser (prefs showHelpOnError) parser >>= print
parser :: ParserInfo Options
parser = info (helper <*> parseOptions) $
mconcat [
fullDesc,
progDesc "X-program",
header "x 0.0.1" ]
parseOptions :: Parser Options
parseOptions = Options
<$> timeoutOpt
<*> parseCommand
where
timeoutOpt = optional $ option auto $
long "timeout" <> short 't' <> metavar "INT" <>
help "specify a timeout for the query"
parseCommand :: Parser Command
parseCommand = subparser (domains <> zones)
where
domains = mkcmd "domains" "this does domain stuff" $
subparser $ mconcat [
mkcmd "list" "this lists" (ListDomains <$> limitOpt),
mkcmd "create" "this creates" (CreateDomain <$> domainArg),
mkcmd "get" "this gets" (GetDomain <$> domainArg) ]
zones = mkcmd "zones" "this does zones stuff" $
subparser $ mconcat [
mkcmd "list" "this lists" (ListZones <$> limitOpt),
mkcmd "get" "this gets" (GetZone <$> zoneArg) ]
limitOpt = optional $ option auto $
long "limit" <> short 'l' <> metavar "INT" <>
help "limit the number of printed results"
-- Domain list|create <domain>|get <domain>|delete <domain>
-- Zones list|get <zone>
mkcmd :: String -> String -> Parser a -> Mod CommandFields a
mkcmd cmd desc parser =
command cmd $ info (helper <*> parser) $ progDesc desc
domainArg :: Parser String
domainArg = strArgument (metavar "DOMAIN")
zoneArg :: Parser String
zoneArg = strArgument (metavar "ZONE")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment