{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wno-deprecations #-}

-- | Wrapper of 'Network.Socket.Lazy.ByteString' for the 'effectful' ecosystem.
-- Please see the documentation of 'Network.Socket.Lazy.ByteString' on how to use
-- this library.
module Effectful.Network.Lazy where

import Effectful (Eff, type (:>))

import Effectful.Dispatch.Static (unsafeEff_)

import Data.ByteString.Lazy (LazyByteString)
import Network.Socket (Socket)
import Network.Socket.ByteString.Lazy qualified as S
import Prelude hiding (getContents)

import Data.Int (Int64)
import Effectful.Network (Network)

#if MIN_VERSION_network(3,2,0)
import System.Posix.Types (Fd)
#endif

-- | Wraps 'S.send'.
send :: (Network :> es) => Socket -> LazyByteString -> Eff es Int64
send :: forall (es :: [Effect]).
(Network :> es) =>
Socket -> LazyByteString -> Eff es Int64
send Socket
sock = IO Int64 -> Eff es Int64
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO Int64 -> Eff es Int64)
-> (LazyByteString -> IO Int64) -> LazyByteString -> Eff es Int64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> LazyByteString -> IO Int64
S.send Socket
sock

-- | Wraps 'S.sendAll'.
sendAll :: (Network :> es) => Socket -> LazyByteString -> Eff es ()
sendAll :: forall (es :: [Effect]).
(Network :> es) =>
Socket -> LazyByteString -> Eff es ()
sendAll Socket
sock = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (LazyByteString -> IO ()) -> LazyByteString -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> LazyByteString -> IO ()
S.sendAll Socket
sock

#if MIN_VERSION_network(3,2,0)
-- | Wraps 'S.sendWithFds'.
sendWithFds :: (Network :> es) => Socket -> LazyByteString -> [Fd] -> Eff es ()
sendWithFds :: forall (es :: [Effect]).
(Network :> es) =>
Socket -> LazyByteString -> [Fd] -> Eff es ()
sendWithFds Socket
sock LazyByteString
lbs = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ()) -> ([Fd] -> IO ()) -> [Fd] -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> LazyByteString -> [Fd] -> IO ()
S.sendWithFds Socket
sock LazyByteString
lbs
#endif

-- | Wraps 'S.getContents'.
getContents :: (Network :> es) => Socket -> Eff es LazyByteString
getContents :: forall (es :: [Effect]).
(Network :> es) =>
Socket -> Eff es LazyByteString
getContents = IO LazyByteString -> Eff es LazyByteString
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO LazyByteString -> Eff es LazyByteString)
-> (Socket -> IO LazyByteString) -> Socket -> Eff es LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> IO LazyByteString
S.getContents

-- | Wraps 'S.recv'.
recv :: (Network :> es) => Socket -> Int64 -> Eff es LazyByteString
recv :: forall (es :: [Effect]).
(Network :> es) =>
Socket -> Int64 -> Eff es LazyByteString
recv Socket
sock = IO LazyByteString -> Eff es LazyByteString
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO LazyByteString -> Eff es LazyByteString)
-> (Int64 -> IO LazyByteString) -> Int64 -> Eff es LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Socket -> Int64 -> IO LazyByteString
S.recv Socket
sock