module Chiasma.Interpreter.ProcessOutput where

import Data.Attoparsec.ByteString (parse)
import Data.Attoparsec.Types (IResult (Done, Fail, Partial))
import Polysemy.Conc (interpretAtomic)
import Polysemy.Process.Effect.ProcessOutput (ProcessOutput (Chunk))

import Chiasma.Data.TmuxOutputBlock (TmuxOutputBlock)
import Chiasma.Native.TmuxOutputBlock (parser)

type ParseResult =
  IResult ByteString TmuxOutputBlock

type ParseCont =
  ByteString -> IResult ByteString TmuxOutputBlock

parseResult ::
  Member (AtomicState (Maybe ParseCont)) r =>
  ParseResult ->
  Sem r ([Either Text TmuxOutputBlock], ByteString)
parseResult :: forall (r :: EffectRow).
Member (AtomicState (Maybe ParseCont)) r =>
ParseResult -> Sem r ([Either Text TmuxOutputBlock], ByteString)
parseResult = \case
  Fail ByteString
_ [String]
_ String
err -> ([Either Text TmuxOutputBlock], ByteString)
-> Sem r ([Either Text TmuxOutputBlock], ByteString)
forall a. a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Text -> Either Text TmuxOutputBlock
forall a b. a -> Either a b
Left (String -> Text
forall a. ToText a => a -> Text
toText String
err)], ByteString
"")
  Partial ParseCont
c -> ([], ByteString
"") ([Either Text TmuxOutputBlock], ByteString)
-> Sem r () -> Sem r ([Either Text TmuxOutputBlock], ByteString)
forall a b. a -> Sem r b -> Sem r a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Maybe ParseCont -> Sem r ()
forall s (r :: EffectRow).
Member (AtomicState s) r =>
s -> Sem r ()
atomicPut (ParseCont -> Maybe ParseCont
forall a. a -> Maybe a
Just ParseCont
c)
  Done ByteString
rest TmuxOutputBlock
block -> ([Either Text TmuxOutputBlock], ByteString)
-> Sem r ([Either Text TmuxOutputBlock], ByteString)
forall a. a -> Sem r a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([TmuxOutputBlock -> Either Text TmuxOutputBlock
forall a b. b -> Either a b
Right TmuxOutputBlock
block], ByteString
rest)

interpretProcessOutputTmuxBlock ::
   p r .
  Member (Embed IO) r =>
  InterpreterFor (ProcessOutput p (Either Text TmuxOutputBlock)) r
interpretProcessOutputTmuxBlock :: forall (p :: OutputPipe) (r :: EffectRow).
Member (Embed IO) r =>
InterpreterFor (ProcessOutput p (Either Text TmuxOutputBlock)) r
interpretProcessOutputTmuxBlock =
  Maybe ParseCont -> InterpreterFor (AtomicState (Maybe ParseCont)) r
forall a (r :: EffectRow).
Member (Embed IO) r =>
a -> InterpreterFor (AtomicState a) r
interpretAtomic (Maybe ParseCont
forall a. Maybe a
Nothing :: Maybe ParseCont) (Sem (AtomicState (Maybe ParseCont) : r) a -> Sem r a)
-> (Sem (ProcessOutput p (Either Text TmuxOutputBlock) : r) a
    -> Sem (AtomicState (Maybe ParseCont) : r) a)
-> Sem (ProcessOutput p (Either Text TmuxOutputBlock) : r) a
-> Sem r a
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
  (forall (rInitial :: EffectRow) x.
 ProcessOutput p (Either Text TmuxOutputBlock) (Sem rInitial) x
 -> Sem (AtomicState (Maybe ParseCont) : r) x)
-> Sem
     (ProcessOutput p (Either Text TmuxOutputBlock)
        : AtomicState (Maybe ParseCont) : r)
     a
-> Sem (AtomicState (Maybe ParseCont) : r) a
forall (e :: (* -> *) -> * -> *) (r :: EffectRow) a.
FirstOrder e "interpret" =>
(forall (rInitial :: EffectRow) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Chunk ByteString
_ ByteString
new ->
      (Maybe ParseCont -> (Maybe ParseCont, Maybe ParseCont))
-> Sem (AtomicState (Maybe ParseCont) : r) (Maybe ParseCont)
forall s a (r :: EffectRow).
Member (AtomicState s) r =>
(s -> (s, a)) -> Sem r a
atomicState' (Maybe ParseCont
forall a. Maybe a
Nothing,) Sem (AtomicState (Maybe ParseCont) : r) (Maybe ParseCont)
-> (Maybe ParseCont -> Sem (AtomicState (Maybe ParseCont) : r) x)
-> Sem (AtomicState (Maybe ParseCont) : r) x
forall a b.
Sem (AtomicState (Maybe ParseCont) : r) a
-> (a -> Sem (AtomicState (Maybe ParseCont) : r) b)
-> Sem (AtomicState (Maybe ParseCont) : r) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Just ParseCont
cont ->
          ParseResult
-> Sem
     (AtomicState (Maybe ParseCont) : r)
     ([Either Text TmuxOutputBlock], ByteString)
forall (r :: EffectRow).
Member (AtomicState (Maybe ParseCont)) r =>
ParseResult -> Sem r ([Either Text TmuxOutputBlock], ByteString)
parseResult (ParseCont
cont ByteString
new)
        Maybe ParseCont
Nothing ->
          ParseResult
-> Sem
     (AtomicState (Maybe ParseCont) : r)
     ([Either Text TmuxOutputBlock], ByteString)
forall (r :: EffectRow).
Member (AtomicState (Maybe ParseCont)) r =>
ParseResult -> Sem r ([Either Text TmuxOutputBlock], ByteString)
parseResult (Parser TmuxOutputBlock -> ParseCont
forall a. Parser a -> ByteString -> Result a
parse Parser TmuxOutputBlock
parser ByteString
new)
  (Sem
   (ProcessOutput p (Either Text TmuxOutputBlock)
      : AtomicState (Maybe ParseCont) : r)
   a
 -> Sem (AtomicState (Maybe ParseCont) : r) a)
-> (Sem (ProcessOutput p (Either Text TmuxOutputBlock) : r) a
    -> Sem
         (ProcessOutput p (Either Text TmuxOutputBlock)
            : AtomicState (Maybe ParseCont) : r)
         a)
-> Sem (ProcessOutput p (Either Text TmuxOutputBlock) : r) a
-> Sem (AtomicState (Maybe ParseCont) : r) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sem (ProcessOutput p (Either Text TmuxOutputBlock) : r) a
-> Sem
     (ProcessOutput p (Either Text TmuxOutputBlock)
        : AtomicState (Maybe ParseCont) : r)
     a
forall (e2 :: (* -> *) -> * -> *) (e1 :: (* -> *) -> * -> *)
       (r :: EffectRow) a.
Sem (e1 : r) a -> Sem (e1 : e2 : r) a
raiseUnder