{-# Language GADTs, KindSignatures #-}
module Client.Commands.Arguments
( ArgumentSpec(..)
, parseArguments
) where
import Control.Monad
data ArgumentSpec :: * -> * where
ReqTokenArg :: String -> ArgumentSpec rest -> ArgumentSpec (String, rest)
OptTokenArg :: String -> ArgumentSpec rest -> ArgumentSpec (Maybe (String, rest))
RemainingArg :: String -> ArgumentSpec String
NoArg :: ArgumentSpec ()
instance Show (ArgumentSpec s) where
showsPrec p spec =
case spec of
ReqTokenArg s rest -> showParen (p >= 11)
$ showString "ReqTokenArg "
. showsPrec 11 s . showChar ' ' . showsPrec 11 rest
OptTokenArg s rest -> showParen (p >= 11)
$ showString "OptTokenArg "
. showsPrec 11 s . showChar ' ' . showsPrec 11 rest
RemainingArg s -> showParen (p >= 11)
$ showString "RemainingArg " . showsPrec 11 s
NoArg -> showString "NoArg"
parseArguments ::
ArgumentSpec a ->
String ->
Maybe a
parseArguments arg xs =
case arg of
NoArg -> guard (all (==' ') xs)
RemainingArg _ -> Just (drop 1 xs)
OptTokenArg _ rest ->
do let (tok, xs') = nextToken xs
if null tok
then Just Nothing
else do rest' <- parseArguments rest xs'
return (Just (tok, rest'))
ReqTokenArg _ rest ->
do let (tok, xs') = nextToken xs
guard (not (null tok))
rest' <- parseArguments rest xs'
return (tok, rest')
nextToken :: String -> (String, String)
nextToken = break (==' ') . dropWhile (==' ')