module Hemokit.Start
( EmotivArgs (..)
, emotivArgsParser
, parseModel
, parseArgs
, getEmotivDeviceFromArgs
) where
import Options.Applicative
import System.IO (stdin)
import Hemokit hiding (serial)
data EmotivArgs = EmotivArgs
{ model :: EmotivModel
, serial :: Maybe SerialNumber
, fromFile :: Maybe FilePath
} deriving (Eq, Ord, Show)
parseModel :: Monad m => String -> m EmotivModel
parseModel s = case s of
"consumer" -> return Consumer
"developer" -> return Developer
_ -> fail "Model is not valid. Must be 'consumer' or 'developer'."
emotivArgsParser :: Parser EmotivArgs
emotivArgsParser = EmotivArgs
<$> option (eitherReader parseModel)
( long "model" <> metavar "MODEL"
<> value Consumer
<> help "Consumer or Developer model, Consumer by default" )
<*> (optional . option (maybeReader makeSerialNumberFromString "Serial number of has invalid format"))
( long "serial" <> metavar "SERIALNUMBER"
<> help "The serial to use. If no --from-file is given, this will select the device" )
<*> (optional . strOption)
( long "from-file" <> metavar "PATH"
<> help "The file path to read from (e.g. /dev/hidraw0 or myfile.dump)" )
where
maybeReader :: (String -> Maybe a) -> String -> ReadM a
maybeReader mbFn msg = eitherReader (maybe (fail msg) pure . mbFn)
parseArgs :: String -> Parser a -> IO a
parseArgs programDescription parser = execParser $ info (helper <*> parser)
(progDesc programDescription)
getEmotivDeviceFromArgs :: EmotivArgs -> IO (Either String EmotivDevice)
getEmotivDeviceFromArgs EmotivArgs{ model, serial, fromFile } = case fromFile of
Just f | Just s <- serial -> Right <$> if f == "-" then openEmotivDeviceHandle model s stdin
else openEmotivDeviceFile model s f
| otherwise -> fail "A serial number must be provided when using --from-file"
Nothing -> do
devices <- getEmotivDevices
case devices of
[] -> fail "No devices found."
_ -> case serial of
Just s -> case reverse [ d | d <- devices, deviceInfoSerial d == Just s ] of
[] -> fail $ "No device with serial " ++ show s
d:_ -> print d >> Right <$> openEmotivDevice model d
_ -> print (last devices) >> Right <$> openEmotivDevice model (last devices)