module Chiasma.Native.Parse where

import qualified Data.Text as T (pack)
import Prelude hiding (many, try)
import Text.Parsec (
  ParseError,
  many,
  manyTill,
  parse,
  skipMany,
  try,
  )
import Text.Parsec.Char (anyChar, endOfLine, string)
import Text.Parsec.Text (GenParser)

tillEol :: GenParser st Text
tillEol :: forall st. GenParser st Text
tillEol = String -> Text
T.pack (String -> Text)
-> ParsecT Text st Identity String -> ParsecT Text st Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text st Identity Char
-> ParsecT Text st Identity Char -> ParsecT Text st Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT Text st Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar ParsecT Text st Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
endOfLine

beginLine :: GenParser st Text
beginLine :: forall st. GenParser st Text
beginLine = String -> ParsecT Text st Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"%begin" ParsecT Text st Identity String
-> ParsecT Text st Identity Text -> ParsecT Text st Identity Text
forall a b.
ParsecT Text st Identity a
-> ParsecT Text st Identity b -> ParsecT Text st Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Text st Identity Text
forall st. GenParser st Text
tillEol

endLine :: GenParser st Text
endLine :: forall st. GenParser st Text
endLine = String -> ParsecT Text st Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"%end" ParsecT Text st Identity String
-> ParsecT Text st Identity Text -> ParsecT Text st Identity Text
forall a b.
ParsecT Text st Identity a
-> ParsecT Text st Identity b -> ParsecT Text st Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Text st Identity Text
forall st. GenParser st Text
tillEol

parseBlock :: GenParser st [Text]
parseBlock :: forall st. GenParser st [Text]
parseBlock = do
  [Text]
_ <- ParsecT Text st Identity Text
-> ParsecT Text st Identity Text -> GenParser st [Text]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT Text st Identity Text
forall st. GenParser st Text
tillEol (ParsecT Text st Identity Text -> ParsecT Text st Identity Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT Text st Identity Text
forall st. GenParser st Text
beginLine)
  ParsecT Text st Identity Text
-> ParsecT Text st Identity Text -> GenParser st [Text]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT Text st Identity Text
forall st. GenParser st Text
tillEol (ParsecT Text st Identity Text -> ParsecT Text st Identity Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT Text st Identity Text
forall st. GenParser st Text
endLine)

resultParser :: GenParser st [[Text]]
resultParser :: forall st. GenParser st [[Text]]
resultParser =
  ParsecT Text st Identity [Text]
-> ParsecT Text st Identity [[Text]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT Text st Identity [Text] -> ParsecT Text st Identity [Text]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT Text st Identity [Text]
forall st. GenParser st [Text]
parseBlock) ParsecT Text st Identity [[Text]]
-> ParsecT Text st Identity () -> ParsecT Text st Identity [[Text]]
forall a b.
ParsecT Text st Identity a
-> ParsecT Text st Identity b -> ParsecT Text st Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text st Identity Text -> ParsecT Text st Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text st Identity Text
forall st. GenParser st Text
tillEol

resultLines :: Text -> Either ParseError [[Text]]
resultLines :: Text -> Either ParseError [[Text]]
resultLines = Parsec Text () [[Text]]
-> String -> Text -> Either ParseError [[Text]]
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse Parsec Text () [[Text]]
forall st. GenParser st [[Text]]
resultParser String
"tmux output"