{-# options_haddock prune #-}

-- |Description: ProcessOutput Interpreters, Internal
module Polysemy.Process.Interpreter.ProcessOutput where

import qualified Data.ByteString as ByteString

import Polysemy.Process.Effect.ProcessOutput (ProcessOutput (Chunk))

-- |Interpret 'ProcessOutput' by immediately emitting raw 'ByteString's without accumulation.
interpretProcessOutputId :: InterpreterFor (ProcessOutput ByteString) r
interpretProcessOutputId :: forall (r :: [Effect]). InterpreterFor (ProcessOutput ByteString) r
interpretProcessOutputId =
  (forall (rInitial :: [Effect]) x.
 ProcessOutput ByteString (Sem rInitial) x -> Sem r x)
-> Sem (ProcessOutput ByteString : r) a -> Sem r a
forall (e :: Effect) (r :: [Effect]) a.
FirstOrder e "interpret" =>
(forall (rInitial :: [Effect]) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Chunk ByteString
buffer ByteString
new ->
      ([ByteString], ByteString) -> Sem r ([ByteString], ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([ByteString
buffer ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
new], ByteString
"")
{-# inline interpretProcessOutputId #-}

splitLines :: ByteString -> ByteString -> ([ByteString], ByteString)
splitLines :: ByteString -> ByteString -> ([ByteString], ByteString)
splitLines ByteString
buffer ByteString
new =
  (Maybe ByteString -> ByteString)
-> ([ByteString], Maybe ByteString) -> ([ByteString], ByteString)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second Maybe ByteString -> ByteString
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold ((ByteString
 -> ([ByteString], Maybe ByteString)
 -> ([ByteString], Maybe ByteString))
-> ([ByteString], Maybe ByteString)
-> [ByteString]
-> ([ByteString], Maybe ByteString)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr' ByteString
-> ([ByteString], Maybe ByteString)
-> ([ByteString], Maybe ByteString)
forall {a}. a -> ([a], Maybe a) -> ([a], Maybe a)
folder ([], Maybe ByteString
forall a. Maybe a
Nothing) [ByteString]
parts)
  where
    parts :: [ByteString]
parts =
      Word8 -> ByteString -> [ByteString]
ByteString.split Word8
10 (ByteString
buffer ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
new)
    folder :: a -> ([a], Maybe a) -> ([a], Maybe a)
folder a
a ([a]
z, Maybe a
Nothing) =
      ([a]
z, a -> Maybe a
forall a. a -> Maybe a
Just a
a)
    folder a
a ([a]
z, Just a
r) =
      (a
a a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
z, a -> Maybe a
forall a. a -> Maybe a
Just a
r)

-- |Interpret 'ProcessOutput' by emitting individual 'ByteString' lines of output.
interpretProcessOutputLines :: InterpreterFor (ProcessOutput ByteString) r
interpretProcessOutputLines :: forall (r :: [Effect]). InterpreterFor (ProcessOutput ByteString) r
interpretProcessOutputLines =
  (forall (rInitial :: [Effect]) x.
 ProcessOutput ByteString (Sem rInitial) x -> Sem r x)
-> Sem (ProcessOutput ByteString : r) a -> Sem r a
forall (e :: Effect) (r :: [Effect]) a.
FirstOrder e "interpret" =>
(forall (rInitial :: [Effect]) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Chunk ByteString
buffer ByteString
new ->
      ([ByteString], ByteString) -> Sem r ([ByteString], ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> ByteString -> ([ByteString], ByteString)
splitLines ByteString
buffer ByteString
new)
{-# inline interpretProcessOutputLines #-}

-- |Interpret 'ProcessOutput' by immediately emitting 'Text' without accumulation.
interpretProcessOutputText :: InterpreterFor (ProcessOutput Text) r
interpretProcessOutputText :: forall (r :: [Effect]). InterpreterFor (ProcessOutput Text) r
interpretProcessOutputText =
  (forall (rInitial :: [Effect]) x.
 ProcessOutput Text (Sem rInitial) x -> Sem r x)
-> Sem (ProcessOutput Text : r) a -> Sem r a
forall (e :: Effect) (r :: [Effect]) a.
FirstOrder e "interpret" =>
(forall (rInitial :: [Effect]) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Chunk ByteString
buffer ByteString
new ->
      ([Text], ByteString) -> Sem r ([Text], ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 (ByteString
buffer ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> ByteString
new)], ByteString
"")
{-# inline interpretProcessOutputText #-}

-- |Interpret 'ProcessOutput' by emitting individual 'Text' lines of output.
interpretProcessOutputTextLines :: InterpreterFor (ProcessOutput Text) r
interpretProcessOutputTextLines :: forall (r :: [Effect]). InterpreterFor (ProcessOutput Text) r
interpretProcessOutputTextLines =
  (forall (rInitial :: [Effect]) x.
 ProcessOutput Text (Sem rInitial) x -> Sem r x)
-> Sem (ProcessOutput Text : r) a -> Sem r a
forall (e :: Effect) (r :: [Effect]) a.
FirstOrder e "interpret" =>
(forall (rInitial :: [Effect]) x. e (Sem rInitial) x -> Sem r x)
-> Sem (e : r) a -> Sem r a
interpret \case
    Chunk ByteString
buffer ByteString
new ->
      ([Text], ByteString) -> Sem r ([Text], ByteString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (([ByteString] -> [Text])
-> ([ByteString], ByteString) -> ([Text], ByteString)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((ByteString -> Text) -> [ByteString] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8) (ByteString -> ByteString -> ([ByteString], ByteString)
splitLines ByteString
buffer ByteString
new))
{-# inline interpretProcessOutputTextLines #-}