module Polysemy.FS.Scoped.Text.Internal where
import qualified System.IO as IO
import Polysemy
( Member, Sem, embed, Embed, InterpretersFor, Members, interpret )
import qualified Polysemy.SequentialAccess.Text as SAT
import qualified Polysemy.SequentialAccess as SA
import Polysemy.Internal.Kind ( Append )
import Polysemy.Resource ( Resource )
import Control.Category ( (>>>) )
import Data.Functor ( (<&>) )
import Polysemy.FS.Scoped.Internal as Scoped
( ScopedFile, scopedFileToIO, seekToBegin, seekToEnd )
import qualified Polysemy.FS.Scoped as Scoped
import Polysemy.Internal.Sing ( KnownList )
import qualified Data.Text.IO as TIO
import qualified GHC.IO.Handle as IO
readToIO :: Member (Embed IO) r => IO.Handle -> Sem (SAT.ReadLine ': SAT.ReadToEnd ': r) a -> Sem r a
readToIO :: Handle -> Sem (ReadLine : ReadToEnd : r) a -> Sem r a
readToIO Handle
h =
(forall (rInitial :: EffectRow) x.
ReadLine (Sem rInitial) x -> Sem (ReadToEnd : r) x)
-> Sem (ReadLine : ReadToEnd : r) a -> Sem (ReadToEnd : 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 (\(SA.Read SAT.Line) -> IO Text -> Sem (ReadToEnd : r) Text
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO Text -> Sem (ReadToEnd : r) Text)
-> IO Text -> Sem (ReadToEnd : r) Text
forall a b. (a -> b) -> a -> b
$ Handle -> IO Text
TIO.hGetLine Handle
h)
(Sem (ReadLine : ReadToEnd : r) a -> Sem (ReadToEnd : r) a)
-> (Sem (ReadToEnd : r) a -> Sem r a)
-> Sem (ReadLine : ReadToEnd : r) a
-> Sem r a
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (rInitial :: EffectRow) x.
ReadToEnd (Sem rInitial) x -> Sem r x)
-> Sem (ReadToEnd : r) a -> Sem 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
( \(SA.Read SA.ToEnd) ->
IO Text -> Sem r Text
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO Text -> Sem r Text) -> IO Text -> Sem r Text
forall a b. (a -> b) -> a -> b
$ (Handle -> IO Text
TIO.hGetContents (Handle -> IO Text) -> IO Handle -> IO Text
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Handle -> IO Handle
IO.hDuplicate Handle
h) IO Text -> IO () -> IO Text
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Handle -> IO ()
seekToEnd Handle
h
)
extendToIO :: Member (Embed IO) r => IO.Handle -> Sem (SAT.Extend ': r) a -> Sem r a
extendToIO :: Handle -> Sem (Extend : r) a -> Sem r a
extendToIO Handle
h = (forall (rInitial :: EffectRow) x.
Extend (Sem rInitial) x -> Sem r x)
-> Sem (Extend : r) a -> Sem 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 \(SA.Extend t) -> IO () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO () -> Sem r ()) -> IO () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ Handle -> IO () -> IO ()
forall a. Handle -> IO a -> IO a
restoreCursor Handle
h (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Handle -> IO ()
seekToEnd Handle
h IO () -> IO () -> IO ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Handle -> Text -> IO ()
TIO.hPutStr Handle
h Text
t
restoreCursor :: IO.Handle -> IO a -> IO a
restoreCursor :: Handle -> IO a -> IO a
restoreCursor Handle
h IO a
m = do
Integer
before <- Handle -> IO Integer
IO.hTell Handle
h
IO a
m IO a -> IO () -> IO a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Handle -> SeekMode -> Integer -> IO ()
IO.hSeek Handle
h SeekMode
IO.AbsoluteSeek Integer
before
clearToIO :: Member (Embed IO) r => IO.Handle -> Sem (SAT.Clear ': r) a -> Sem r a
clearToIO :: Handle -> Sem (Clear : r) a -> Sem r a
clearToIO Handle
h = (forall (rInitial :: EffectRow) x.
Clear (Sem rInitial) x -> Sem r x)
-> Sem (Clear : r) a -> Sem 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 \(SA.Resize SA.NullSize) -> IO () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO () -> Sem r ()) -> IO () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ Handle -> Integer -> IO ()
IO.hSetFileSize Handle
h Integer
0
cursorToIO :: Member (Embed IO) r => IO.Handle -> Sem (Append SAT.Cursor r) a -> Sem r a
cursorToIO :: Handle -> Sem (Append Cursor r) a -> Sem r a
cursorToIO Handle
h =
(forall (rInitial :: EffectRow) x.
GetPosition TriPosition (Sem rInitial) x -> Sem (Seek Ends : r) x)
-> Sem (GetPosition TriPosition : Seek Ends : r) a
-> Sem (Seek Ends : 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
( \GetPosition TriPosition (Sem rInitial) x
SA.GetPosition -> IO TriPosition -> Sem (Seek Ends : r) TriPosition
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO TriPosition -> Sem (Seek Ends : r) TriPosition)
-> IO TriPosition -> Sem (Seek Ends : r) TriPosition
forall a b. (a -> b) -> a -> b
$
Handle -> IO Integer
IO.hTell Handle
h IO Integer -> (Integer -> IO TriPosition) -> IO TriPosition
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Integer
0 -> TriPosition -> IO TriPosition
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TriPosition -> IO TriPosition) -> TriPosition -> IO TriPosition
forall a b. (a -> b) -> a -> b
$ Ends -> TriPosition
SA.End Ends
SA.TOF
Integer
_ -> Handle -> IO Bool
IO.hIsEOF Handle
h IO Bool -> (Bool -> TriPosition) -> IO TriPosition
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Bool
False -> TriPosition
SA.Intermediate
Bool
True -> Ends -> TriPosition
SA.End Ends
SA.EOF
)
(Sem (GetPosition TriPosition : Seek Ends : r) a
-> Sem (Seek Ends : r) a)
-> (Sem (Seek Ends : r) a -> Sem r a)
-> Sem (GetPosition TriPosition : Seek Ends : r) a
-> Sem r a
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (forall (rInitial :: EffectRow) x.
Seek Ends (Sem rInitial) x -> Sem r x)
-> Sem (Seek Ends : r) a -> Sem 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
(\(SA.Seek end) -> IO () -> Sem r ()
forall (m :: * -> *) (r :: EffectRow) a.
Member (Embed m) r =>
m a -> Sem r a
embed (IO () -> Sem r ()) -> IO () -> Sem r ()
forall a b. (a -> b) -> a -> b
$ case Ends
end of
Ends
SA.TOF -> Handle -> IO ()
seekToBegin Handle
h
Ends
SA.EOF -> Handle -> IO ()
seekToEnd Handle
h
)
scopedTextFileToIO
:: (Members '[Embed IO, Resource] r, KnownList es)
=> IO.IOMode
-> (IO.Handle -> InterpretersFor es r)
-> (∀handle'. Sem (Scoped.ScopedFile mode es b handle' ': r) a)
-> Sem r a
scopedTextFileToIO :: IOMode
-> (Handle -> InterpretersFor es r)
-> (forall handle'. Sem (ScopedFile mode es b handle' : r) a)
-> Sem r a
scopedTextFileToIO = (FilePath -> IOMode -> IO Handle)
-> IOMode
-> (Handle -> InterpretersFor es r)
-> (forall handle'. Sem (ScopedFile mode es b handle' : r) a)
-> Sem r a
forall k (r :: EffectRow) (es :: EffectRow) (mode :: k) b a.
(Members '[Embed IO, Resource] r, KnownList es) =>
(FilePath -> IOMode -> IO Handle)
-> IOMode
-> (Handle -> InterpretersFor es r)
-> (forall handle'. Sem (ScopedFile mode es b handle' : r) a)
-> Sem r a
Scoped.scopedFileToIO FilePath -> IOMode -> IO Handle
IO.openFile