-- | 'TBQueue' helpers for static 'Concurrent' effect.
--
-- @since 0.1
module Effectful.Concurrent.STM.TBQueue.Static
  ( -- * TBQueue

    -- ** Strict
    readTBQueue',
    tryReadTBQueue',
    writeTBQueue',
    flushTBQueue',

    -- *** Atomic
    readTBQueueA',
    tryReadTBQueueA',
    writeTBQueueA',
    flushTBQueueA',

    -- ** Lazy
    TBQueue.newTBQueue,
    TBQueue.readTBQueue,
    TBQueue.tryReadTBQueue,
    TBQueue.writeTBQueue,
    TBQueue.flushTBQueue,

    -- *** Atomic
    newTBQueueA,
    readTBQueueA,
    tryReadTBQueueA,
    writeTBQueueA,
    flushTBQueueA,

    -- * Re-exports
    Concurrent,
    runConcurrent,
    TBQueue,
    Natural,
  )
where

import Control.Concurrent.STM.TBQueue (TBQueue)
import Control.Concurrent.STM.TBQueue qualified as TBQueue
import Control.Monad ((>=>))
import Effectful (Eff, type (:>))
import Effectful.Concurrent.STM (Concurrent, STM, atomically, runConcurrent)
import Effectful.Concurrent.STM.Utils (evaluateSTM)
import Numeric.Natural (Natural)

-- | @since 0.1
newTBQueueA :: (Concurrent :> es) => Natural -> Eff es (TBQueue a)
newTBQueueA :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
Natural -> Eff es (TBQueue a)
newTBQueueA = STM (TBQueue a) -> Eff es (TBQueue a)
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM (TBQueue a) -> Eff es (TBQueue a))
-> (Natural -> STM (TBQueue a)) -> Natural -> Eff es (TBQueue a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> STM (TBQueue a)
forall a. Natural -> STM (TBQueue a)
TBQueue.newTBQueue

-- | @since 0.1
readTBQueue' :: TBQueue a -> STM a
readTBQueue' :: forall a. TBQueue a -> STM a
readTBQueue' = TBQueue a -> STM a
forall a. TBQueue a -> STM a
TBQueue.readTBQueue (TBQueue a -> STM a) -> (a -> STM a) -> TBQueue a -> STM a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> STM a
forall a. a -> STM a
evaluateSTM

-- | @since 0.1
readTBQueueA :: (Concurrent :> es) => TBQueue a -> Eff es a
readTBQueueA :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> Eff es a
readTBQueueA = STM a -> Eff es a
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM a -> Eff es a)
-> (TBQueue a -> STM a) -> TBQueue a -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM a
forall a. TBQueue a -> STM a
TBQueue.readTBQueue

-- | @since 0.1
readTBQueueA' :: (Concurrent :> es) => TBQueue a -> Eff es a
readTBQueueA' :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> Eff es a
readTBQueueA' = STM a -> Eff es a
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM a -> Eff es a)
-> (TBQueue a -> STM a) -> TBQueue a -> Eff es a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM a
forall a. TBQueue a -> STM a
readTBQueue'

-- | @since 0.1
tryReadTBQueue' :: TBQueue a -> STM (Maybe a)
tryReadTBQueue' :: forall a. TBQueue a -> STM (Maybe a)
tryReadTBQueue' =
  TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
TBQueue.tryReadTBQueue (TBQueue a -> STM (Maybe a))
-> (Maybe a -> STM (Maybe a)) -> TBQueue a -> STM (Maybe a)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \case
    Maybe a
Nothing -> Maybe a -> STM (Maybe a)
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
    Just a
x -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> STM a -> STM (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> STM a
forall a. a -> STM a
evaluateSTM a
x

-- | @since 0.1
tryReadTBQueueA :: (Concurrent :> es) => TBQueue a -> Eff es (Maybe a)
tryReadTBQueueA :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> Eff es (Maybe a)
tryReadTBQueueA = STM (Maybe a) -> Eff es (Maybe a)
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM (Maybe a) -> Eff es (Maybe a))
-> (TBQueue a -> STM (Maybe a)) -> TBQueue a -> Eff es (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
TBQueue.tryReadTBQueue

-- | @since 0.1
tryReadTBQueueA' :: (Concurrent :> es) => TBQueue a -> Eff es (Maybe a)
tryReadTBQueueA' :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> Eff es (Maybe a)
tryReadTBQueueA' = STM (Maybe a) -> Eff es (Maybe a)
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM (Maybe a) -> Eff es (Maybe a))
-> (TBQueue a -> STM (Maybe a)) -> TBQueue a -> Eff es (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM (Maybe a)
forall a. TBQueue a -> STM (Maybe a)
tryReadTBQueue'

-- | @since 0.1
writeTBQueue' :: TBQueue a -> a -> STM ()
writeTBQueue' :: forall a. TBQueue a -> a -> STM ()
writeTBQueue' TBQueue a
q = a -> STM a
forall a. a -> STM a
evaluateSTM (a -> STM a) -> (a -> STM ()) -> a -> STM ()
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
TBQueue.writeTBQueue TBQueue a
q

-- | @since 0.1
writeTBQueueA :: (Concurrent :> es) => TBQueue a -> a -> Eff es ()
writeTBQueueA :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> a -> Eff es ()
writeTBQueueA TBQueue a
q = STM () -> Eff es ()
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM () -> Eff es ()) -> (a -> STM ()) -> a -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
TBQueue.writeTBQueue TBQueue a
q

-- | @since 0.1
writeTBQueueA' :: (Concurrent :> es) => TBQueue a -> a -> Eff es ()
writeTBQueueA' :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> a -> Eff es ()
writeTBQueueA' TBQueue a
q = STM () -> Eff es ()
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM () -> Eff es ()) -> (a -> STM ()) -> a -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> a -> STM ()
forall a. TBQueue a -> a -> STM ()
writeTBQueue' TBQueue a
q

-- | @since 0.1
flushTBQueue' :: TBQueue a -> STM [a]
flushTBQueue' :: forall a. TBQueue a -> STM [a]
flushTBQueue' = TBQueue a -> STM [a]
forall a. TBQueue a -> STM [a]
TBQueue.flushTBQueue (TBQueue a -> STM [a]) -> ([a] -> STM [a]) -> TBQueue a -> STM [a]
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> [a] -> STM [a]
forall a. a -> STM a
evaluateSTM

-- | @since 0.1
flushTBQueueA :: (Concurrent :> es) => TBQueue a -> Eff es [a]
flushTBQueueA :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> Eff es [a]
flushTBQueueA = STM [a] -> Eff es [a]
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM [a] -> Eff es [a])
-> (TBQueue a -> STM [a]) -> TBQueue a -> Eff es [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM [a]
forall a. TBQueue a -> STM [a]
TBQueue.flushTBQueue

-- | @since 0.1
flushTBQueueA' :: (Concurrent :> es) => TBQueue a -> Eff es [a]
flushTBQueueA' :: forall (es :: [Effect]) a.
(Concurrent :> es) =>
TBQueue a -> Eff es [a]
flushTBQueueA' = STM [a] -> Eff es [a]
forall (es :: [Effect]) a. (Concurrent :> es) => STM a -> Eff es a
atomically (STM [a] -> Eff es [a])
-> (TBQueue a -> STM [a]) -> TBQueue a -> Eff es [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TBQueue a -> STM [a]
forall a. TBQueue a -> STM [a]
flushTBQueue'