-- | Contains types representing the command-line configuration options of the CLI -- along with parsers to parse command-line arguments into configuration values. module Options ( ConfigCommand(..), ServiceCommand(..), NotificationCommand(..), ClientCommand(..), ClientOptions(..), parseCmdLineArgs ) where -------------------------------------------------------------------------------- import Data.Aeson import Data.Text import Data.ByteString.Lazy.Char8 qualified as C8 import Options.Applicative -------------------------------------------------------------------------------- -- | Represents commands related to the Home Assistant configuration. data ConfigCommand = ShowConfig | CheckConfig | ReloadAllConfig showConfigP :: Parser ConfigCommand showConfigP = pure ShowConfig checkConfigP :: Parser ConfigCommand checkConfigP = pure ShowConfig reloadAllConfigP :: Parser ConfigCommand reloadAllConfigP = pure ReloadAllConfig -------------------------------------------------------------------------------- -- | Represents commands related to Home Assistant services. data ServiceCommand = ListServices listServicesP :: Parser ServiceCommand listServicesP = pure ListServices -------------------------------------------------------------------------------- -- | Represents commands related to the notification service. data NotificationCommand = SendNotification { -- | The name of the service to send the notification to. sendNotificationDevice :: Text, -- | The message to send. sendNotificationMessage :: Text, -- | Arbitrary data to send. sendNotificationData :: Maybe Value } sendNotificationP :: Parser NotificationCommand sendNotificationP = SendNotification <$> argument str (metavar "DEVICE") <*> argument str (metavar "MESSAGE") <*> optional (option (eitherReader (eitherDecode . C8.pack)) (long "data")) -------------------------------------------------------------------------------- data ClientCommand = ConfigCommand ConfigCommand | ServiceCommand ServiceCommand | NotificationCommand NotificationCommand configP :: Parser ClientCommand configP = fmap ConfigCommand $ subparser $ command "show" (info (showConfigP <**> helper) (progDesc "Show the Home Assistant configuration")) <> command "check" (info (checkConfigP <**> helper) (progDesc "Check the Home Assistant configuration")) <> command "reload-all" (info (reloadAllConfigP <**> helper) (progDesc "Reloads all Home Assistant configurations")) servicesP :: Parser ClientCommand servicesP = fmap ServiceCommand $ subparser $ command "list" (info (listServicesP <**> helper) (progDesc "Lists all Home Assistant services")) notificationP :: Parser ClientCommand notificationP = fmap NotificationCommand $ subparser $ command "send" (info (sendNotificationP <**> helper) (progDesc "Send a notification")) clientCommandP :: Parser ClientCommand clientCommandP = subparser $ command "config" (info (configP <**> helper) (progDesc "Configuration commands")) <> command "services" (info (servicesP <**> helper) (progDesc "Services commands")) <> command "notification" (info (notificationP <**> helper) (progDesc "Notification service commands")) -------------------------------------------------------------------------------- data ClientOptions = MkClientOptions { clientAddress :: Maybe Text, clientOptionsCommand :: ClientCommand } optionsP :: Parser ClientOptions optionsP = MkClientOptions <$> optional (strOption (long "address" <> metavar "URL" <> help "The address of the Home Assistant server")) <*> clientCommandP opts :: ParserInfo ClientOptions opts = info (optionsP <**> helper) idm parseCmdLineArgs :: IO ClientOptions parseCmdLineArgs = execParser opts --------------------------------------------------------------------------------