module System.Console.Docopt.Types
where
import Data.Ord (comparing)
import Data.Map (Map)
import qualified Data.Map as M
import Data.List (nub)
import System.Console.Docopt.ParseUtils
type Name = String
data Pattern a = Sequence [Pattern a]
| OneOf [Pattern a]
| Unordered [Pattern a]
| Optional (Pattern a)
| Repeated (Pattern a)
| Atom a
deriving (Show, Eq)
atoms :: Eq a => Pattern a -> [a]
atoms (Sequence ps) = foldl (++) [] $ map atoms ps
atoms (OneOf ps) = foldl (++) [] $ map atoms $ nub ps
atoms (Unordered ps) = foldl (++) [] $ map atoms $ nub ps
atoms (Optional p) = atoms p
atoms (Repeated p) = atoms p
atoms (Atom a) = [a]
data Option = LongOption Name
| ShortOption Char
| Command Name
| Argument Name
| AnyOption
deriving (Show, Eq, Ord)
type OptPattern = Pattern Option
humanize :: Option -> String
humanize opt = case opt of
Command name -> name
Argument name -> name
LongOption name -> "--"++name
ShortOption c -> ['-',c]
AnyOption -> "[options]"
data OptionInfo = OptionInfo
{ synonyms :: [Option]
, defaultVal :: Maybe String
, expectsVal :: Bool
, isRepeated :: Bool
} deriving (Show, Eq)
fromSynList :: [Option] -> OptionInfo
fromSynList opts = OptionInfo { synonyms = opts
, defaultVal = Nothing
, expectsVal = False
, isRepeated = False }
type OptInfoMap = Map Option OptionInfo
type OptFormat = (OptPattern, OptInfoMap)
data OptParserState = OptParserState
{ optInfoMap :: OptInfoMap
, parsedArgs :: Arguments
, inShortOptStack :: Bool
, inTopLevelSequence :: Bool
} deriving (Show)
fromOptInfoMap :: OptInfoMap -> OptParserState
fromOptInfoMap m = OptParserState { optInfoMap = m
, parsedArgs = M.empty
, inShortOptStack = False
, inTopLevelSequence = True }
data ArgValue = MultiValue [String]
| Value String
| NoValue
| Counted Int
| Present
| NotPresent
deriving (Show, Eq, Ord)
type Arguments = Map Option ArgValue
data Docopt = Docopt { optFormat :: OptFormat
, usage :: String
}