module EnvStatus.Output.Parse where
import Data.Functor (($>))
import Data.List (delete)
import Text.Parsec (many, parse, try)
import Text.Parsec.Char (anyChar, char, noneOf, oneOf, string)
import Text.Parsec.Combinator (choice, eof, manyTill, notFollowedBy)
import Text.Parsec.Prim ((<|>), (<?>))
import Text.Parsec.String (Parser)
import EnvStatus.Output.Types (Token(..))
parseOutputFormat :: String -> [Token]
parseOutputFormat outputFormat =
case parsed of
Right matches -> matches
Left _ -> []
where
parsed = parse (manyTill tokenParser eof) "" outputFormat
tokenParser :: Parser Token
tokenParser = choice [
commandParser
, rawParser
] <?> "token"
singleOpenCurly :: Parser Char
singleOpenCurly = do
c <- char '{'
_ <- notFollowedBy $ char '{'
return c
rawParser :: Parser Token
rawParser = do
parsed <- many (try singleOpenCurly <|> noneOf ['{'])
return $ Raw parsed
commandParser :: Parser Token
commandParser = do
_ <- char '{'
_ <- char '{'
parsed <- manyTill anyChar (try $ string "}}")
return $ SubCommand parsed
outputFormatParser :: Parser [Token]
outputFormatParser =
manyTill tokenParser eof
quotedOption :: Parser String
quotedOption = do
_ <- char '"'
manyTill anyChar (char '"')
separator :: Parser Char
separator = oneOf [' ', '\t', '\n', '\r']
skipSeparator :: Parser ()
skipSeparator = separator $> ()
word :: Parser String
word = do
_ <- many separator
manyTill anyChar (try skipSeparator <|> eof)
commandPart :: Parser String
commandPart = try quotedOption <|> word
parseCommand :: String -> [String]
parseCommand cmd =
case parsed of
Right matches -> delete "" matches
Left _ -> [""]
where
parsed = parse (manyTill commandPart eof) "" cmd