git-fmt-0.2.1.0: src/Git/Fmt/Config.hs
{-|
Module : Git.Fmt.Config
Description : Configuration data structures.
Copyright : (c) Henry J. Wylde, 2015
License : BSD3
Maintainer : public@hjwylde.com
Configuration data structures.
-}
{-# LANGUAGE OverloadedStrings #-}
module Git.Fmt.Config (
-- * Config
Config(..),
emptyConfig, programFor, unsafeProgramFor, supported,
-- * Program
Program(..),
emptyProgram, substitute, usesInputVariable, usesOutputVariable, inputVariableName,
outputVariableName,
-- * Helper functions
defaultFileName,
) where
import Data.Aeson.Types
import Data.HashMap.Lazy (toList)
import Data.List.Extra (find)
import Data.Maybe (fromJust, isJust)
import Data.Text (Text, isInfixOf, replace)
-- | A list of programs.
data Config = Config {
programs :: [Program]
}
deriving (Eq, Show)
instance FromJSON Config where
parseJSON (Object obj) = Config <$> mapM (\(key, value) ->
parseJSON value >>= \program -> return program { name = key }
) (toList obj)
parseJSON value = typeMismatch "Config" value
-- | The empty config (no programs).
emptyConfig :: Config
emptyConfig = Config []
-- | Attempts to find a program for the given extension.
programFor :: Config -> Text -> Maybe Program
programFor config ext = find (\program -> ext `elem` extensions program) (programs config)
-- | Finds a program for the given extension or errors.
unsafeProgramFor :: Config -> Text -> Program
unsafeProgramFor config = fromJust . programFor config
-- | Checks if the given extension is supported (e.g., there is a program for it).
supported :: Config -> Text -> Bool
supported config = isJust . programFor config
-- | A program has a semantic name, associated extensions and command.
-- The command string may contain variables to be replaced by surrounding them with '{{..}}'.
data Program = Program {
name :: Text,
extensions :: [Text],
command :: Text
}
deriving (Eq, Show)
instance FromJSON Program where
parseJSON (Object obj) = Program "" <$> obj .: "extensions" <*> obj .: "command"
parseJSON value = typeMismatch "Program" value
-- | The empty program (the command fails).
emptyProgram :: Program
emptyProgram = Program "" [] "false"
-- | Substitutes the mapping throughout the command.
substitute :: Text -> [(Text, Text)] -> Text
substitute = foldr (uncurry replace)
-- | Checks whether the text uses the input variable.
usesInputVariable :: Text -> Bool
usesInputVariable = isInfixOf inputVariableName
-- | Checks whether the text uses the output variable.
usesOutputVariable :: Text -> Bool
usesOutputVariable = isInfixOf outputVariableName
-- | The input variable name.
inputVariableName :: Text
inputVariableName = "{{input}}"
-- | The output variable name.
outputVariableName :: Text
outputVariableName = "{{output}}"
-- | The file name of the default config.
defaultFileName :: FilePath
defaultFileName = ".omnifmt.yaml"