{-# LANGUAGE ApplicativeDo, OverloadedStrings #-}

{-|
Module      : Client.Configuration.Macros
Description : Configuration schema for macros
Copyright   : (c) Eric Mertens, 2017
License     : ISC
Maintainer  : emertens@gmail.com

-}

module Client.Configuration.Macros
  ( macroMapSpec
  , macroCommandSpec
  ) where

import           Config.Schema.Spec
import           Client.Commands.Interpolation
import           Client.Commands.Recognizer
import           Data.Maybe (fromMaybe)
import           Data.Text (Text)

macroMapSpec :: ValueSpec (Recognizer Macro)
macroMapSpec :: ValueSpec (Recognizer Macro)
macroMapSpec = [(Text, Macro)] -> Recognizer Macro
forall a. [(Text, a)] -> Recognizer a
fromCommands ([(Text, Macro)] -> Recognizer Macro)
-> ValueSpec [(Text, Macro)] -> ValueSpec (Recognizer Macro)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ValueSpec (Text, Macro) -> ValueSpec [(Text, Macro)]
forall a. ValueSpec a -> ValueSpec [a]
listSpec ValueSpec (Text, Macro)
macroValueSpec

macroValueSpec :: ValueSpec (Text, Macro)
macroValueSpec :: ValueSpec (Text, Macro)
macroValueSpec = Text -> SectionsSpec (Text, Macro) -> ValueSpec (Text, Macro)
forall a. Text -> SectionsSpec a -> ValueSpec a
sectionsSpec Text
"macro" (SectionsSpec (Text, Macro) -> ValueSpec (Text, Macro))
-> SectionsSpec (Text, Macro) -> ValueSpec (Text, Macro)
forall a b. (a -> b) -> a -> b
$
  do Text
name     <- Text -> Text -> SectionsSpec Text
forall a. HasSpec a => Text -> Text -> SectionsSpec a
reqSection Text
"name" Text
""
     MacroSpec
spec     <- MacroSpec -> Maybe MacroSpec -> MacroSpec
forall a. a -> Maybe a -> a
fromMaybe MacroSpec
noMacroArguments
             (Maybe MacroSpec -> MacroSpec)
-> SectionsSpec (Maybe MacroSpec) -> SectionsSpec MacroSpec
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> ValueSpec MacroSpec -> Text -> SectionsSpec (Maybe MacroSpec)
forall a. Text -> ValueSpec a -> Text -> SectionsSpec (Maybe a)
optSection' Text
"arguments" ValueSpec MacroSpec
macroArgumentsSpec Text
""
     [[ExpansionChunk]]
commands <- Text
-> ValueSpec [[ExpansionChunk]]
-> Text
-> SectionsSpec [[ExpansionChunk]]
forall a. Text -> ValueSpec a -> Text -> SectionsSpec a
reqSection' Text
"commands" (ValueSpec [ExpansionChunk] -> ValueSpec [[ExpansionChunk]]
forall a. ValueSpec a -> ValueSpec [a]
oneOrList ValueSpec [ExpansionChunk]
macroCommandSpec) Text
""
     return (Text
name, Text -> MacroSpec -> [[ExpansionChunk]] -> Macro
Macro Text
name MacroSpec
spec [[ExpansionChunk]]
commands)

macroArgumentsSpec :: ValueSpec MacroSpec
macroArgumentsSpec :: ValueSpec MacroSpec
macroArgumentsSpec = Text
-> ValueSpec Text
-> (Text -> Either Text MacroSpec)
-> ValueSpec MacroSpec
forall a b.
Text -> ValueSpec a -> (a -> Either Text b) -> ValueSpec b
customSpec Text
"macro-arguments" ValueSpec Text
forall a. HasSpec a => ValueSpec a
anySpec Text -> Either Text MacroSpec
parseMacroSpecs

macroCommandSpec :: ValueSpec [ExpansionChunk]
macroCommandSpec :: ValueSpec [ExpansionChunk]
macroCommandSpec = Text
-> ValueSpec Text
-> (Text -> Either Text [ExpansionChunk])
-> ValueSpec [ExpansionChunk]
forall a b.
Text -> ValueSpec a -> (a -> Either Text b) -> ValueSpec b
customSpec Text
"macro-command" ValueSpec Text
forall a. HasSpec a => ValueSpec a
anySpec Text -> Either Text [ExpansionChunk]
parseExpansion