module Data.Text.Format.Simple.Internal where
import Control.Applicative
import Data.Attoparsec.Combinator
import Data.Attoparsec.Text as A
import Data.Either
import qualified Data.Foldable as F
import Data.String
import Data.Text (Text)
import qualified Data.Text as T
import GHC.Exts
type Name = Text
data Part
= String Text
| NamedVar Name
deriving Eq
newtype Compiled = Compiled { unCompiled :: [Part] } deriving Eq
instance Show Compiled where
show = show . T.unpack . T.concat . map f . unCompiled
where
f (String s) = s
f (NamedVar n) = "${" `mappend` n `mappend` "}"
instance IsString Compiled where
fromString = either error id . Data.Text.Format.Simple.Internal.parse . fromString
parse :: Text -> Either String Compiled
parse = parseOnly parser
parser :: Parser Compiled
parser = Compiled <$> partParser `manyTill` endOfInput
partParser :: Parser Part
partParser = NamedVar <$> parseVar <|> String <$> parseString
parseVar :: Parser Name
parseVar = do
char '$'
char '{'
str <- A.takeWhile (/= '}')
char '}'
return str
parseString :: Parser Text
parseString = do
str <- A.takeWhile (/= '$')
rest <- (lookAhead (string "${") >> return "")
<|> (T.cons <$> char '$' <*> parseString)
<|> return ""
return $ str `mappend` rest