module System.Console.CmdArgs.Implicit.Local(
local, err,
Prog_(..), progSumm, Mode_(..), Flag_(..), isFlag_
) where
import System.Console.CmdArgs.Implicit.Ann
import System.Console.CmdArgs.Implicit.Type
import System.Console.CmdArgs.Implicit.Read
import System.Console.CmdArgs.Explicit
import System.Console.CmdArgs.Annotate
import System.Console.CmdArgs.Default
import Data.Char
import Data.Generics.Any
import Data.Maybe
data Prog_ = Prog_
{progModes :: [Mode_]
,progSummary :: Maybe String
,progProgram :: String
,progHelp :: String
,progVerbosity :: Bool
} deriving Show
instance Default Prog_ where
def = Prog_ def def def def def
progSumm x = fromMaybe ("The " ++ progProgram x ++ " program") $ progSummary x
data Mode_ = Mode_
{modeFlags_ :: [Flag_]
,modeMode :: Mode (CmdArgs Any)
,modeDefault :: Bool
,modeGroup :: Maybe String
,modeExplicit :: Bool
} deriving Show
instance Default Mode_ where
def = Mode_ [] m def def def
where m = Mode (toGroup []) [] undefined Right "" [] Nothing (toGroup [])
data Flag_
= Flag_
{flagField :: String
,flagFlag :: Flag (CmdArgs Any)
,flagExplicit :: Bool
,flagGroup :: Maybe String
,flagEnum :: Maybe String
}
| Arg_
{flagArg_ :: Arg (CmdArgs Any)
,flagArgPos :: Maybe Int
,flagArgOpt :: Maybe String
}
deriving Show
instance Default Flag_ where
def = Flag_ "" undefined def def def
isFlag_ Flag_{} = True
isFlag_ _ = False
withMode x f = x{modeMode = f $ modeMode x}
withFlagArg x f = x{flagArg_ = f $ flagArg_ x}
withFlagFlag x f = x{flagFlag = f $ flagFlag x}
err x y = error $ "System.Console.CmdArgs.Implicit, unexpected " ++ x ++ ": " ++ y
errFlag x y = err ("flag (" ++ x ++ ")") y
local :: Capture Ann -> Prog_
local = prog_ . defaultMissing
prog_ :: Capture Ann -> Prog_
prog_ (Ann a b) = progAnn a $ prog_ b
prog_ (Many xs) = def{progModes=map mode_ xs, progProgram=prog}
where prog = map toLower $ typeShell $ fromCapture $ head xs
prog_ x@Ctor{} = prog_ $ Many [x]
prog_ x = err "program" $ show x
mode_ :: Capture Ann -> Mode_
mode_ (Ann a b) = modeAnn a $ mode_ b
mode_ o@(Ctor x ys) = withMode def{modeFlags_=concat $ zipWith flag_ (fields x) ys} $ \x -> x{modeValue=embed $ fromCapture o}
mode_ x = err "mode" $ show x
flag_ :: String -> Capture Ann -> [Flag_]
flag_ name (Ann a b) = map (flagAnn a) $ flag_ name b
flag_ name (Value x) = [def{flagField=name, flagFlag = remap embed reembed $ value_ name x}]
flag_ name x@Ctor{} = flag_ name $ Value $ fromCapture x
flag_ name (Many xs) = map (enum_ name) xs
flag_ name x = errFlag name $ show x
enum_ :: String -> Capture Ann -> Flag_
enum_ name (Ann a b) = flagAnn a $ enum_ name b
enum_ name (Value x) = def{flagField=name, flagFlag = flagNone [] (fmap $ setField (name,x)) "", flagEnum=Just $ ctor x}
enum_ name x@Ctor{} = enum_ name $ Value $ fromCapture x
enum_ name x = errFlag name $ show x
value_ :: String -> Any -> Flag Any
value_ name x
| isNothing mty = errFlag name $ show x
| isReadBool ty =
let upd b x = setField (name,addContainer ty (getField name x) (Any b)) x
in flagBool [] upd ""
| otherwise =
let upd s x = fmap (\c -> setField (name,c) x) $ reader ty s $ getField name x
in flagReq [] upd (readHelp ty) ""
where
mty = toReadContainer x
ty = fromJust mty
progAnn :: Ann -> Prog_ -> Prog_
progAnn (ProgSummary a) x = x{progSummary=Just a}
progAnn (ProgProgram a) x = x{progProgram=a}
progAnn ProgVerbosity x = x{progVerbosity=True}
progAnn (Help a) x | length (progModes x) > 1 = x{progHelp=a}
progAnn a x | length (progModes x) == 1 = x{progModes = map (modeAnn a) $ progModes x}
progAnn a x = err "program" $ show a
modeAnn :: Ann -> Mode_ -> Mode_
modeAnn (Help a) x = withMode x $ \x -> x{modeHelp=a}
modeAnn (ModeHelpSuffix a) x = withMode x $ \x -> x{modeHelpSuffix=a}
modeAnn ModeDefault x = x{modeDefault=True}
modeAnn (GroupName a) x = x{modeGroup=Just a}
modeAnn Explicit x = x{modeExplicit=True}
modeAnn a x = err "mode" $ show a
flagAnn :: Ann -> Flag_ -> Flag_
flagAnn (FlagType a) x@Arg_{} = withFlagArg x $ \x -> x{argType=a}
flagAnn (FlagType a) x@Flag_{} = withFlagFlag x $ \x -> x{flagType=a}
flagAnn (Help a) x@Flag_{} = withFlagFlag x $ \x -> x{flagHelp=a}
flagAnn (FlagArgPos a) x = toArg x $ Just a
flagAnn FlagArgs x = toArg x Nothing
flagAnn Explicit x@Flag_{} = x{flagExplicit=True}
flagAnn (FlagOptional a) x@Flag_{flagEnum=Nothing,flagFlag=Flag{flagInfo=FlagReq}} = withFlagFlag x $ \x -> x{flagInfo=FlagOpt a}
flagAnn (FlagOptional a) x@Arg_{} = x{flagArgOpt=Just a}
flagAnn (Name a) x@Flag_{} = withFlagFlag x $ \x -> x{flagNames = a : flagNames x}
flagAnn (GroupName a) x@Flag_{} = x{flagGroup=Just a}
flagAnn a x = errFlag (head $ words $ show x) $ show a
toArg :: Flag_ -> Maybe Int -> Flag_
toArg (Flag_ fld x False Nothing Nothing) pos
| null (flagNames x), null (flagHelp x), Just y <- opt $ flagInfo x
= Arg_ (Arg (flagValue x) (flagType x)) pos y
where
opt FlagReq = Just Nothing
opt (FlagOpt x) = Just (Just x)
opt (FlagOptRare x) = Just Nothing
opt _ = Nothing
toArg a _ = errFlag "args/argPos" $ show a