{-# Language OverloadedStrings #-}
module Client.Commands.Interpolation
( ExpansionChunk(..)
, parseExpansion
, resolveExpansions
) where
import Control.Applicative
import Data.Attoparsec.Text as P
import Data.Char
import qualified Data.Text as Text
import Data.Text (Text)
data ExpansionChunk
= LiteralChunk Text
| VariableChunk Text
| IntegerChunk Integer
deriving Show
parseExpansion :: Text -> Maybe [ExpansionChunk]
parseExpansion txt =
case parseOnly (many parseChunk <* endOfInput) txt of
Left{} -> Nothing
Right chunks -> Just chunks
parseChunk :: Parser ExpansionChunk
parseChunk =
choice
[ LiteralChunk <$> P.takeWhile1 (/= '$')
, LiteralChunk "$" <$ P.string "$$"
, string "${" *> parseVariable <* char '}'
, char '$' *> parseVariable
]
parseVariable :: Parser ExpansionChunk
parseVariable = IntegerChunk <$> P.decimal
<|> VariableChunk <$> P.takeWhile1 isAlpha
resolveExpansions ::
(Text -> Maybe Text) ->
(Integer -> Maybe Text) ->
[ExpansionChunk] ->
Maybe Text
resolveExpansions var arg xs = Text.concat <$> traverse resolve1 xs
where
resolve1 (LiteralChunk lit) = Just lit
resolve1 (VariableChunk v) = var v
resolve1 (IntegerChunk i) = arg i