{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-} -- | CmdItem is a tool to build command lines. module Data.CmdItem where import Control.Applicative ((<$>)) import Data.Either (either, partitionEithers) import Data.List (intercalate) import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Monoid import Data.Text (Text, pack) import qualified Data.Text as T import GHC.Exts import Text.Templater (template) data CmdItem = CmdItem { fragments :: [Text] -- pieces of command line , localVars :: Map Text Text -- context of substitution } deriving (Show, Eq) -- | Renders a command line item to a @Text@ string -- This will throw an error if anything goes wrong render :: CmdItem -> IO Text render c = either error return (renderEither c) -- | Renders a command line item to a @Maybe Text@ renderMaybe :: CmdItem -> Maybe Text renderMaybe c = either (const Nothing) return (renderEither c) -- | Renders a command line item to a @Either String Text@ renderEither :: CmdItem -> Either String Text renderEither (CmdItem {..}) = let (lefts, rights) = partitionEithers $ (\x -> template x (`M.lookup` localVars)) <$> fragments isOk = null lefts in if isOk then Right $ T.intercalate " " rights else Left $ intercalate ", " lefts instance Monoid CmdItem where mempty = CmdItem mempty mempty mappend (CmdItem cmdA localA) (CmdItem cmdB localB) = CmdItem (cmdA <> cmdB) (localA <> localB) instance IsString CmdItem where fromString "" = mempty fromString st = CmdItem [pack st] mempty #if MIN_VERSION_base(4,7,0) instance IsList CmdItem where type Item CmdItem = (Text, Text) fromList [] = mempty fromList lst = CmdItem mempty (M.fromList lst) toList (CmdItem _ m) = M.toList m #endif