packages feed

ribosome-host-0.9.9.9: lib/Ribosome/Host/Interpreter/Process/Socket.hs

module Ribosome.Host.Interpreter.Process.Socket where

import Data.Serialize (Serialize)
import qualified Network.Socket as Socket
import Network.Socket (socketToHandle)
import Path (toFilePath)
import Polysemy.Process (Process, ProcessOptions, interpretProcessHandles)
import Polysemy.Process.Data.ProcessError (ProcessError)
import System.IO (Handle, IOMode (ReadWriteMode))

import Ribosome.Host.Data.BootError (BootError (BootError))
import Ribosome.Host.Data.NvimSocket (NvimSocket (NvimSocket))
import Ribosome.Host.Interpreter.Process.Cereal (interpretProcessInputCereal, interpretProcessOutputCereal)

withSocket ::
  Members [Reader NvimSocket, Resource, Error BootError, Embed IO] r =>
  (Handle -> Sem r a) ->
  Sem r a
withSocket use =
  bracket acquire release \ socket ->
    use =<< embed (socketToHandle socket ReadWriteMode)
  where
    acquire = do
      NvimSocket path <- ask
      fromEither . first BootError =<< tryAny do
        socket <- Socket.socket Socket.AF_UNIX Socket.Stream 0
        socket <$ Socket.connect socket (Socket.SockAddrUnix (toFilePath path))
    release =
      tryAny_ . Socket.close

interpretProcessCerealSocket ::
  ∀ a r .
  Serialize a =>
  Members [Reader NvimSocket, Error BootError, Log, Resource, Race, Async, Embed IO] r =>
  ProcessOptions ->
  InterpreterFor (Process a (Either Text a) !! ProcessError) r
interpretProcessCerealSocket options sem =
  withSocket \ handle ->
    interpretProcessOutputCereal $
    interpretProcessInputCereal $
    interpretProcessHandles options handle handle (raiseUnder2 sem)