module System.Hardware.Serialport.Cli
  ( SerialPortCli(..)
  , serialPortCli
  , -- * Parsers
    serialPortCliParser
  , serialPortPathParser
  , serialPortSettingsParser
  , commSpeedParser
  , bitsPerWordParser
  , stopBitsParser
  , parityParser
  , flowControlParser
  , timeoutParser
  ) where

import Data.Word
import Options.Applicative
import System.Hardware.Serialport.Types

data SerialPortCli = SerialPortCli
  { SerialPortCli -> FilePath
serialPortPath     :: FilePath
  , SerialPortCli -> SerialPortSettings
serialPortSettings :: SerialPortSettings
  }

serialPortCli :: IO SerialPortCli
serialPortCli :: IO SerialPortCli
serialPortCli =
  ParserPrefs -> ParserInfo SerialPortCli -> IO SerialPortCli
forall a. ParserPrefs -> ParserInfo a -> IO a
customExecParser ParserPrefs
serialPortCliPrefs (ParserInfo SerialPortCli -> IO SerialPortCli)
-> ParserInfo SerialPortCli -> IO SerialPortCli
forall a b. (a -> b) -> a -> b
$
    Parser SerialPortCli
-> InfoMod SerialPortCli -> ParserInfo SerialPortCli
forall a. Parser a -> InfoMod a -> ParserInfo a
info (Parser SerialPortCli
serialPortCliParser Parser SerialPortCli
-> Parser (SerialPortCli -> SerialPortCli) -> Parser SerialPortCli
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> Parser (SerialPortCli -> SerialPortCli)
forall a. Parser (a -> a)
helper) InfoMod SerialPortCli
forall a. Monoid a => a
mempty

serialPortCliPrefs :: ParserPrefs
serialPortCliPrefs :: ParserPrefs
serialPortCliPrefs = PrefsMod -> ParserPrefs
prefs (PrefsMod -> ParserPrefs) -> PrefsMod -> ParserPrefs
forall a b. (a -> b) -> a -> b
$ PrefsMod
showHelpOnError PrefsMod -> PrefsMod -> PrefsMod
forall a. Semigroup a => a -> a -> a
<> PrefsMod
showHelpOnEmpty

serialPortCliParser :: Parser SerialPortCli
serialPortCliParser :: Parser SerialPortCli
serialPortCliParser =
  FilePath -> SerialPortSettings -> SerialPortCli
SerialPortCli
    (FilePath -> SerialPortSettings -> SerialPortCli)
-> Parser FilePath -> Parser (SerialPortSettings -> SerialPortCli)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser FilePath
serialPortPathParser
    Parser (SerialPortSettings -> SerialPortCli)
-> Parser SerialPortSettings -> Parser SerialPortCli
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser SerialPortSettings
serialPortSettingsParser

serialPortPathParser :: Parser FilePath
serialPortPathParser :: Parser FilePath
serialPortPathParser = Mod ArgumentFields FilePath -> Parser FilePath
forall s. IsString s => Mod ArgumentFields s -> Parser s
strArgument (Mod ArgumentFields FilePath -> Parser FilePath)
-> Mod ArgumentFields FilePath -> Parser FilePath
forall a b. (a -> b) -> a -> b
$ [Mod ArgumentFields FilePath] -> Mod ArgumentFields FilePath
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"serial port file path"
  , FilePath -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"<tty-device>"
  , Completer -> Mod ArgumentFields FilePath
forall (f :: * -> *) a. HasCompleter f => Completer -> Mod f a
completer (Completer -> Mod ArgumentFields FilePath)
-> Completer -> Mod ArgumentFields FilePath
forall a b. (a -> b) -> a -> b
$ FilePath -> Completer
bashCompleter FilePath
"file"
  ]

serialPortSettingsParser :: Parser SerialPortSettings
serialPortSettingsParser :: Parser SerialPortSettings
serialPortSettingsParser =
  CommSpeed
-> Word8
-> StopBits
-> Parity
-> FlowControl
-> Int
-> SerialPortSettings
SerialPortSettings
    (CommSpeed
 -> Word8
 -> StopBits
 -> Parity
 -> FlowControl
 -> Int
 -> SerialPortSettings)
-> Parser CommSpeed
-> Parser
     (Word8
      -> StopBits -> Parity -> FlowControl -> Int -> SerialPortSettings)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser CommSpeed
commSpeedParser
    Parser
  (Word8
   -> StopBits -> Parity -> FlowControl -> Int -> SerialPortSettings)
-> Parser Word8
-> Parser
     (StopBits -> Parity -> FlowControl -> Int -> SerialPortSettings)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Word8
bitsPerWordParser
    Parser
  (StopBits -> Parity -> FlowControl -> Int -> SerialPortSettings)
-> Parser StopBits
-> Parser (Parity -> FlowControl -> Int -> SerialPortSettings)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser StopBits
stopBitsParser
    Parser (Parity -> FlowControl -> Int -> SerialPortSettings)
-> Parser Parity
-> Parser (FlowControl -> Int -> SerialPortSettings)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Parity
parityParser
    Parser (FlowControl -> Int -> SerialPortSettings)
-> Parser FlowControl -> Parser (Int -> SerialPortSettings)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser FlowControl
flowControlParser
    Parser (Int -> SerialPortSettings)
-> Parser Int -> Parser SerialPortSettings
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser Int
timeoutParser

commSpeedParser :: Parser CommSpeed
commSpeedParser :: Parser CommSpeed
commSpeedParser = ReadM CommSpeed -> Mod OptionFields CommSpeed -> Parser CommSpeed
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM CommSpeed
forall a. Read a => ReadM a
auto (Mod OptionFields CommSpeed -> Parser CommSpeed)
-> Mod OptionFields CommSpeed -> Parser CommSpeed
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields CommSpeed] -> Mod OptionFields CommSpeed
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields CommSpeed
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"baudrate"
  , Char -> Mod OptionFields CommSpeed
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'b'
  , CommSpeed -> Mod OptionFields CommSpeed
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value CommSpeed
CS115200
  , Mod OptionFields CommSpeed
forall a (f :: * -> *). Show a => Mod f a
showDefault
  , FilePath -> Mod OptionFields CommSpeed
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"<bps>"
  , FilePath -> Mod OptionFields CommSpeed
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Baud rate"
  ]

bitsPerWordParser :: Parser Word8
bitsPerWordParser :: Parser Word8
bitsPerWordParser = ReadM Word8 -> Mod OptionFields Word8 -> Parser Word8
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Word8
forall a. Read a => ReadM a
auto (Mod OptionFields Word8 -> Parser Word8)
-> Mod OptionFields Word8 -> Parser Word8
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Word8] -> Mod OptionFields Word8
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields Word8
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"databits"
  , Char -> Mod OptionFields Word8
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'd'
  , Word8 -> Mod OptionFields Word8
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (Word8 -> Mod OptionFields Word8)
-> Word8 -> Mod OptionFields Word8
forall a b. (a -> b) -> a -> b
$ SerialPortSettings -> Word8
bitsPerWord SerialPortSettings
defaultSerialSettings
  , Mod OptionFields Word8
forall a (f :: * -> *). Show a => Mod f a
showDefault
  , FilePath -> Mod OptionFields Word8
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"7|8"
  , FilePath -> Mod OptionFields Word8
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Data bits"
  ]

stopBitsParser :: Parser StopBits
stopBitsParser :: Parser StopBits
stopBitsParser = ReadM StopBits -> Mod OptionFields StopBits -> Parser StopBits
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM StopBits
forall a. Read a => ReadM a
auto (Mod OptionFields StopBits -> Parser StopBits)
-> Mod OptionFields StopBits -> Parser StopBits
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields StopBits] -> Mod OptionFields StopBits
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields StopBits
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"stopbits"
  , Char -> Mod OptionFields StopBits
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
's'
  , StopBits -> Mod OptionFields StopBits
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (StopBits -> Mod OptionFields StopBits)
-> StopBits -> Mod OptionFields StopBits
forall a b. (a -> b) -> a -> b
$ SerialPortSettings -> StopBits
stopb SerialPortSettings
defaultSerialSettings
  , Mod OptionFields StopBits
forall a (f :: * -> *). Show a => Mod f a
showDefault
  , FilePath -> Mod OptionFields StopBits
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"One|Two"
  , FilePath -> Mod OptionFields StopBits
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Stop bits"
  ]

parityParser :: Parser Parity
parityParser :: Parser Parity
parityParser = ReadM Parity -> Mod OptionFields Parity -> Parser Parity
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Parity
forall a. Read a => ReadM a
auto (Mod OptionFields Parity -> Parser Parity)
-> Mod OptionFields Parity -> Parser Parity
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Parity] -> Mod OptionFields Parity
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields Parity
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"parity"
  , Char -> Mod OptionFields Parity
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'p'
  , Parity -> Mod OptionFields Parity
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (Parity -> Mod OptionFields Parity)
-> Parity -> Mod OptionFields Parity
forall a b. (a -> b) -> a -> b
$ SerialPortSettings -> Parity
parity SerialPortSettings
defaultSerialSettings
  , Mod OptionFields Parity
forall a (f :: * -> *). Show a => Mod f a
showDefault
  , FilePath -> Mod OptionFields Parity
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"Even|Odd|NoParity"
  , FilePath -> Mod OptionFields Parity
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Parity"
  ]

flowControlParser :: Parser FlowControl
flowControlParser :: Parser FlowControl
flowControlParser = ReadM FlowControl
-> Mod OptionFields FlowControl -> Parser FlowControl
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM FlowControl
forall a. Read a => ReadM a
auto (Mod OptionFields FlowControl -> Parser FlowControl)
-> Mod OptionFields FlowControl -> Parser FlowControl
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields FlowControl] -> Mod OptionFields FlowControl
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields FlowControl
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"flow"
  , Char -> Mod OptionFields FlowControl
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'f'
  , FlowControl -> Mod OptionFields FlowControl
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (FlowControl -> Mod OptionFields FlowControl)
-> FlowControl -> Mod OptionFields FlowControl
forall a b. (a -> b) -> a -> b
$ SerialPortSettings -> FlowControl
flowControl SerialPortSettings
defaultSerialSettings
  , Mod OptionFields FlowControl
forall a (f :: * -> *). Show a => Mod f a
showDefault
  , FilePath -> Mod OptionFields FlowControl
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"Software|NoFlowControl"
  , FilePath -> Mod OptionFields FlowControl
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Flow control"
  ]

timeoutParser :: Parser Int
timeoutParser :: Parser Int
timeoutParser = ReadM Int -> Mod OptionFields Int -> Parser Int
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Int
forall a. Read a => ReadM a
auto (Mod OptionFields Int -> Parser Int)
-> Mod OptionFields Int -> Parser Int
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Int] -> Mod OptionFields Int
forall a. Monoid a => [a] -> a
mconcat
  [ FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => FilePath -> Mod f a
long FilePath
"timeout"
  , Char -> Mod OptionFields Int
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
't'
  , Int -> Mod OptionFields Int
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (Int -> Mod OptionFields Int) -> Int -> Mod OptionFields Int
forall a b. (a -> b) -> a -> b
$ SerialPortSettings -> Int
timeout SerialPortSettings
defaultSerialSettings
  , Mod OptionFields Int
forall a (f :: * -> *). Show a => Mod f a
showDefault
  , FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. HasMetavar f => FilePath -> Mod f a
metavar FilePath
"TIME"
  , FilePath -> Mod OptionFields Int
forall (f :: * -> *) a. FilePath -> Mod f a
help FilePath
"Timeout in tenth-of-seconds"
  ]