{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-} module Options ( TPrint(..) , Operation(..) , Input, Output , Format(..), Source(..), Sink(..) , withArgs , module Options.Utils ) where import Data.Time import GHC.Generics (Generic) import Text.Show.Pretty (PrettyVal) import Thermoprint.Client import Options.Applicative import Options.Utils import Instances () data TPrint = TPrint { baseUrl :: BaseUrl , dryRun :: Bool , output :: Output , operation :: Operation , dumpOptions :: Bool } deriving (Show, Generic, PrettyVal) data Operation = Printers | Jobs { printer :: Maybe PrinterId , jobRange :: Maybe (Range JobId) , timeRange :: Maybe (Range UTCTime) } | JobCreate { printer :: Maybe PrinterId , input :: Input } | Job { jobId :: JobId } | JobStatus { jobId :: JobId } | JobDelete { jobId :: JobId } | Drafts | DraftCreate { draftTitle :: Maybe DraftTitle , input :: Input } | DraftReplace { draftId :: DraftId , draftTitle :: Maybe DraftTitle , input :: Input } | Draft { draftId :: DraftId } | DraftDelete { draftId :: DraftId } | DraftPrint { draftId :: DraftId , printer :: Maybe PrinterId } deriving (Show, Generic, PrettyVal) type Input = (Format, Source) type Output = (Format, Sink ) data Format = Human | BBCode | Internal | JSON deriving (Enum, Bounded, Show, Read, Generic, PrettyVal) data Source = Stdin | ReadFile FilePath deriving (Show, Generic, PrettyVal) data Sink = Stdout | WriteFile FilePath deriving (Show, Generic, PrettyVal) cmdPrinters :: ParserInfo Operation cmdPrinters = info cmdPrinters' $ mconcat [ header "List all available printers" ] where cmdPrinters' = pure Printers cmdJobs :: ParserInfo Operation cmdJobs = info cmdJobs' $ mconcat [ header "List printjobs" ] where cmdJobs' = Jobs <$> optional (option (PrinterId <$> auto) $ metavar "PRINTER" <> long "printer" <> short 'p' <> help "List only jobs associated with printer #PRINTER") <*> pRange (JobId <$> auto) (metavar "JOB") (long "min-job" <> short 'j' <> help "List only jobs with id greater than or equal to JOB") (long "max-job" <> short 'J' <> help "List only jobs with id less than or equal to JOB") <*> pRange rTime (metavar "TIME") (long "min-time" <> short 't' <> help "List only jobs created after or at TIME") (long "max-time" <> short 'T' <> help "List only jobs created before or at TIME") pOperation :: Parser Operation pOperation = hsubparser $ mconcat [ command "printers" cmdPrinters , command "jobs" cmdJobs ] pTPrint :: Parser TPrint pTPrint = TPrint <$> option (eitherReader parseBaseUrl) (metavar "URL" <> long "baseurl" <> short 'u' <> help "Server to interact with" <> value (BaseUrl Http "localhost" 3000) <> showDefaultWith showBaseUrl) <*> switch (long "dry-run" <> short 'n' <> help "Don't send any requests that would be expected to change the servers state" <> showDefault) <*> pOutput <*> pOperation <*> switch (long "dump-options" <> internal) pOutput :: Parser Output pOutput = (,) <$> pOutputFormat <*> pSink where pOutputFormat = option rCI $ metavar "FORMAT" <> long "output-format" <> short 'O' <> help ("Format to use for all output (possible values: " ++ show ([minBound..maxBound] :: [Format]) ++ ")") <> value Human <> showDefault pSink = option rSink $ metavar "PATH" <> long "output" <> short 'o' <> help "Send output to PATH (`-' means stdout)" <> value Stdout <> showDefault rSink = rSink' <$> str where rSink' "-" = Stdout rSink' x = WriteFile x withArgs :: (TPrint -> IO a) -> IO a withArgs a = customExecParser (prefs $ showHelpOnError) (info pTPrint $ header "tprint - A cli interface to Thermoprint.Client") >>= a