{-# LANGUAGE PatternSynonyms #-}

module MusicScroll.Pipeline where

import Control.Concurrent.Async
import Control.Concurrent.MVar
import Control.Concurrent.STM.TVar (TVar)
import Data.Foldable (traverse_)
import Data.Functor.Contravariant.Divisible
import Database.SQLite.Simple
import MusicScroll.DatabaseUtils (insertStrat, updateStrat)
import MusicScroll.LyricsPipeline
import MusicScroll.TrackInfo
  ( TrackIdentifier,
    cleanTrack,
    pattern OnlyMissingArtist,
  )
import MusicScroll.TrackSuplement
import MusicScroll.UIContext (UIContext (..), dischargeOnUI, dischargeOnUISingle)
import Pipes
import Pipes.Concurrent
import qualified Pipes.Prelude as PP

data DBusSignal = Song TrackIdentifier | Error ErrorCause | NoInfo
  deriving (Int -> DBusSignal -> ShowS
[DBusSignal] -> ShowS
DBusSignal -> String
(Int -> DBusSignal -> ShowS)
-> (DBusSignal -> String)
-> ([DBusSignal] -> ShowS)
-> Show DBusSignal
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DBusSignal -> ShowS
showsPrec :: Int -> DBusSignal -> ShowS
$cshow :: DBusSignal -> String
show :: DBusSignal -> String
$cshowList :: [DBusSignal] -> ShowS
showList :: [DBusSignal] -> ShowS
Show)

data AppState = AppState
  { AppState -> UIContext
apUI :: UIContext,
    -- | Enforce mutual exclusion zone
    AppState -> MVar Connection
apDB :: MVar Connection,
    AppState -> TVar (Maybe TrackSuplement)
apSupl :: TVar (Maybe TrackSuplement),
    AppState -> (Input TrackIdentifier, Input ErrorCause)
apStaticinput :: (Input TrackIdentifier, Input ErrorCause),
    -- | Emits only once.
    AppState -> Producer DBusSignal IO ()
apEphemeralInput :: Producer DBusSignal IO ()
  }

staticPipeline :: AppState -> IO ()
staticPipeline :: AppState -> IO ()
staticPipeline (AppState UIContext
ctx MVar Connection
db TVar (Maybe TrackSuplement)
svar (Input TrackIdentifier
dbusTrack, Input ErrorCause
dbusErr) Producer DBusSignal IO ()
_) =
  let songP :: Proxy a' a () TrackIdentifier IO ()
songP =
        Input TrackIdentifier -> Producer' TrackIdentifier IO ()
forall (m :: * -> *) a. MonadIO m => Input a -> Producer' a m ()
fromInput Input TrackIdentifier
dbusTrack Proxy a' a () TrackIdentifier IO ()
-> Proxy () TrackIdentifier () TrackIdentifier IO ()
-> Proxy a' a () TrackIdentifier IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> TVar (Maybe TrackSuplement)
-> Proxy () TrackIdentifier () TrackIdentifier IO ()
forall a.
TVar (Maybe TrackSuplement)
-> Pipe TrackIdentifier TrackIdentifier IO a
addSuplArtist TVar (Maybe TrackSuplement)
svar Proxy a' a () TrackIdentifier IO ()
-> Proxy () TrackIdentifier () TrackIdentifier IO ()
-> Proxy a' a () TrackIdentifier IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Proxy () TrackIdentifier () TrackIdentifier IO ()
forall (m :: * -> *) a.
Functor m =>
Pipe TrackIdentifier TrackIdentifier m a
noRepeatedSongs
          Proxy a' a () TrackIdentifier IO ()
-> Proxy () TrackIdentifier () TrackIdentifier IO ()
-> Proxy a' a () TrackIdentifier IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Proxy () TrackIdentifier () TrackIdentifier IO ()
forall (m :: * -> *) a.
Functor m =>
Pipe TrackIdentifier TrackIdentifier m a
cleanTrack
      errP :: Proxy x' x () ErrorCause IO ()
errP = Input ErrorCause -> Producer' ErrorCause IO ()
forall (m :: * -> *) a. MonadIO m => Input a -> Producer' a m ()
fromInput Input ErrorCause
dbusErr
      errorPipe :: Proxy a' a () X IO ()
errorPipe = Proxy a' a () ErrorCause IO ()
Producer' ErrorCause IO ()
errP Proxy a' a () ErrorCause IO ()
-> Proxy () ErrorCause () SearchResult IO ()
-> Proxy a' a () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (ErrorCause -> SearchResult)
-> Proxy () ErrorCause () SearchResult IO ()
forall (m :: * -> *) a b r. Functor m => (a -> b) -> Pipe a b m r
PP.map ErrorCause -> SearchResult
ErrorOn Proxy a' a () SearchResult IO ()
-> Proxy () SearchResult () X IO () -> Proxy a' a () X IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> UIContext -> Proxy () SearchResult () X IO ()
forall a. UIContext -> Consumer SearchResult IO a
dischargeOnUI UIContext
ctx
   in IO () -> (Async () -> IO ()) -> IO ()
forall a b. IO a -> (Async a -> IO b) -> IO b
withAsync (MVar Connection
-> UIContext -> Producer TrackIdentifier IO () -> IO ()
songPipe MVar Connection
db UIContext
ctx Producer TrackIdentifier IO ()
Producer' TrackIdentifier IO ()
songP) ((Async () -> IO ()) -> IO ()) -> (Async () -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Async ()
songA ->
        IO () -> (Async () -> IO ()) -> IO ()
forall a b. IO a -> (Async a -> IO b) -> IO b
withAsync (Effect IO () -> IO ()
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect Effect IO ()
forall {a'} {a}. Proxy a' a () X IO ()
errorPipe) ((Async () -> IO ()) -> IO ()) -> (Async () -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Async ()
errorA ->
          IO (Async (), ()) -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO (Async (), ()) -> IO ()) -> IO (Async (), ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ [Async ()] -> IO (Async (), ())
forall a. [Async a] -> IO (Async a, a)
waitAnyCancel [Async ()
songA, Async ()
errorA]

songPipe :: MVar Connection -> UIContext -> Producer TrackIdentifier IO () -> IO ()
songPipe :: MVar Connection
-> UIContext -> Producer TrackIdentifier IO () -> IO ()
songPipe MVar Connection
db UIContext
ctx = (Maybe (Async ()) -> TrackIdentifier -> IO (Maybe (Async ())))
-> IO (Maybe (Async ()))
-> (Maybe (Async ()) -> IO ())
-> Producer TrackIdentifier IO ()
-> IO ()
forall (m :: * -> *) x a b.
Monad m =>
(x -> a -> m x) -> m x -> (x -> m b) -> Producer a m () -> m b
PP.foldM Maybe (Async ()) -> TrackIdentifier -> IO (Maybe (Async ()))
go (Maybe (Async ()) -> IO (Maybe (Async ()))
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Async ())
forall a. Maybe a
Nothing) ((Async () -> IO ()) -> Maybe (Async ()) -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Async () -> IO ()
forall a. Async a -> IO ()
cancel)
  where
    go :: Maybe (Async ()) -> TrackIdentifier -> IO (Maybe (Async ()))
    go :: Maybe (Async ()) -> TrackIdentifier -> IO (Maybe (Async ()))
go Maybe (Async ())
asyncVar TrackIdentifier
track =
      do
        (Async () -> IO ()) -> Maybe (Async ()) -> IO ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Async () -> IO ()
forall a. Async a -> IO ()
cancel Maybe (Async ())
asyncVar
        let network :: Proxy a' a () X IO ()
network =
              TrackIdentifier -> Proxy a' a () TrackIdentifier IO ()
forall (m :: * -> *) a x' x. Functor m => a -> Proxy x' x () a m ()
yield TrackIdentifier
track Proxy a' a () TrackIdentifier IO ()
-> Proxy () TrackIdentifier () SearchResult IO ()
-> Proxy a' a () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> MVar Connection -> Proxy () TrackIdentifier () SearchResult IO ()
forall a. MVar Connection -> Pipe TrackIdentifier SearchResult IO a
getLyricsFromAnywhere MVar Connection
db
                Proxy a' a () SearchResult IO ()
-> Proxy () SearchResult () SearchResult IO ()
-> Proxy a' a () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> MVar Connection
-> InsertStategy -> Proxy () SearchResult () SearchResult IO ()
forall a.
MVar Connection
-> InsertStategy -> Pipe SearchResult SearchResult IO a
saveOnDb MVar Connection
db InsertStategy
insertStrat
                Proxy a' a () SearchResult IO ()
-> Proxy () SearchResult () X IO () -> Proxy a' a () X IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> UIContext -> Proxy () SearchResult () X IO ()
forall a. UIContext -> Consumer SearchResult IO a
dischargeOnUI UIContext
ctx
        Async () -> Maybe (Async ())
forall a. a -> Maybe a
Just (Async () -> Maybe (Async ()))
-> IO (Async ()) -> IO (Maybe (Async ()))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO () -> IO (Async ())
forall a. IO a -> IO (Async a)
async (Effect IO () -> IO ()
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect Effect IO ()
forall {a'} {a}. Proxy a' a () X IO ()
network)

suplementPipeline :: TrackSuplement -> AppState -> IO ()
suplementPipeline :: TrackSuplement -> AppState -> IO ()
suplementPipeline TrackSuplement
supl (AppState UIContext
ctx MVar Connection
db TVar (Maybe TrackSuplement)
_ (Input TrackIdentifier, Input ErrorCause)
_ Producer DBusSignal IO ()
signal) =
  let justTracks :: DBusSignal -> Maybe TrackIdentifier
justTracks DBusSignal
a = case DBusSignal
a of Song TrackIdentifier
track -> TrackIdentifier -> Maybe TrackIdentifier
forall a. a -> Maybe a
Just TrackIdentifier
track; DBusSignal
_ -> Maybe TrackIdentifier
forall a. Maybe a
Nothing
      songP :: Producer TrackIdentifier IO ()
songP = Producer DBusSignal IO ()
signal Producer DBusSignal IO ()
-> Proxy () DBusSignal () TrackIdentifier IO ()
-> Producer TrackIdentifier IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (DBusSignal -> Maybe TrackIdentifier)
-> Proxy () DBusSignal () TrackIdentifier IO ()
forall (m :: * -> *) (t :: * -> *) a b r.
(Functor m, Foldable t) =>
(a -> t b) -> Pipe a b m r
PP.mapFoldable DBusSignal -> Maybe TrackIdentifier
justTracks
      pipeline :: Effect IO ()
pipeline =
        Producer TrackIdentifier IO ()
songP Producer TrackIdentifier IO ()
-> Proxy () TrackIdentifier () TrackInfo IO ()
-> Proxy X () () TrackInfo IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> TrackSuplement -> Proxy () TrackIdentifier () TrackInfo IO ()
forall (m :: * -> *) a.
Functor m =>
TrackSuplement -> Pipe TrackIdentifier TrackInfo m a
mergeSuplement TrackSuplement
supl Proxy X () () TrackInfo IO ()
-> Proxy () TrackInfo () SearchResult IO ()
-> Proxy X () () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Proxy () TrackInfo () SearchResult IO ()
forall a. Pipe TrackInfo SearchResult IO a
getLyricsOnlyFromWeb
          Proxy X () () SearchResult IO ()
-> Proxy () SearchResult () SearchResult IO ()
-> Proxy X () () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> MVar Connection
-> InsertStategy -> Proxy () SearchResult () SearchResult IO ()
forall a.
MVar Connection
-> InsertStategy -> Pipe SearchResult SearchResult IO a
saveOnDb MVar Connection
db InsertStategy
insertStrat
          Proxy X () () SearchResult IO ()
-> Proxy () SearchResult () X IO () -> Effect IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> UIContext -> Proxy () SearchResult () X IO ()
dischargeOnUISingle UIContext
ctx
   in Effect IO () -> IO ()
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect Effect IO ()
pipeline

updatePipeline :: TrackSuplement -> AppState -> IO ()
updatePipeline :: TrackSuplement -> AppState -> IO ()
updatePipeline TrackSuplement
supl (AppState UIContext
ctx MVar Connection
db TVar (Maybe TrackSuplement)
_ (Input TrackIdentifier, Input ErrorCause)
_ Producer DBusSignal IO ()
signal) =
  let justTracks :: DBusSignal -> Maybe TrackIdentifier
justTracks DBusSignal
a = case DBusSignal
a of Song TrackIdentifier
track -> TrackIdentifier -> Maybe TrackIdentifier
forall a. a -> Maybe a
Just TrackIdentifier
track; DBusSignal
_ -> Maybe TrackIdentifier
forall a. Maybe a
Nothing
      songP :: Producer TrackIdentifier IO ()
songP = Producer DBusSignal IO ()
signal Producer DBusSignal IO ()
-> Proxy () DBusSignal () TrackIdentifier IO ()
-> Producer TrackIdentifier IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> (DBusSignal -> Maybe TrackIdentifier)
-> Proxy () DBusSignal () TrackIdentifier IO ()
forall (m :: * -> *) (t :: * -> *) a b r.
(Functor m, Foldable t) =>
(a -> t b) -> Pipe a b m r
PP.mapFoldable DBusSignal -> Maybe TrackIdentifier
justTracks
      pipeline :: Effect IO ()
pipeline =
        Producer TrackIdentifier IO ()
songP Producer TrackIdentifier IO ()
-> Proxy () TrackIdentifier () TrackInfo IO ()
-> Proxy X () () TrackInfo IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> TrackSuplement -> Proxy () TrackIdentifier () TrackInfo IO ()
forall (m :: * -> *) a.
Functor m =>
TrackSuplement -> Pipe TrackIdentifier TrackInfo m a
mergeSuplement TrackSuplement
supl Proxy X () () TrackInfo IO ()
-> Proxy () TrackInfo () SearchResult IO ()
-> Proxy X () () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Proxy () TrackInfo () SearchResult IO ()
forall a. Pipe TrackInfo SearchResult IO a
getLyricsOnlyFromWeb
          Proxy X () () SearchResult IO ()
-> Proxy () SearchResult () SearchResult IO ()
-> Proxy X () () SearchResult IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> MVar Connection
-> InsertStategy -> Proxy () SearchResult () SearchResult IO ()
forall a.
MVar Connection
-> InsertStategy -> Pipe SearchResult SearchResult IO a
saveOnDb MVar Connection
db InsertStategy
updateStrat
          Proxy X () () SearchResult IO ()
-> Proxy () SearchResult () X IO () -> Effect IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> UIContext -> Proxy () SearchResult () X IO ()
dischargeOnUISingle UIContext
ctx
   in Effect IO () -> IO ()
forall (m :: * -> *) r. Monad m => Effect m r -> m r
runEffect Effect IO ()
pipeline

debugPS :: Show a => String -> Pipe a a IO ()
debugPS :: forall a. Show a => String -> Pipe a a IO ()
debugPS String
tag = (a -> IO ()) -> Pipe a a IO ()
forall (m :: * -> *) a r. Monad m => (a -> m ()) -> Pipe a a m r
PP.chain (\a
a -> String -> IO ()
putStr String
tag IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> a -> IO ()
forall a. Show a => a -> IO ()
print a
a)

-- | Use the `Output` Divisible instance to create a network. These are
--   1) An output for songs.
--   2) One for errors
--   3) A merge from the previous two.
-- The last one is special as it's non-work-stealing, so we can pass it to
-- multiple listeners and all will receive a signal. But we have to be
-- careful of only taking a single value of it, as it basically a `TVar a`.
musicSpawn ::
  IO
    ( Input TrackIdentifier,
      Input ErrorCause,
      Producer DBusSignal IO (),
      Output TrackIdentifier,
      Output ErrorCause
    )
musicSpawn :: IO
  (Input TrackIdentifier, Input ErrorCause,
   Producer DBusSignal IO (), Output TrackIdentifier,
   Output ErrorCause)
musicSpawn = do
  (Output TrackIdentifier
protoTrackout, Input TrackIdentifier
trackin) <- Buffer TrackIdentifier
-> IO (Output TrackIdentifier, Input TrackIdentifier)
forall a. Buffer a -> IO (Output a, Input a)
spawn (Int -> Buffer TrackIdentifier
forall a. Int -> Buffer a
newest Int
1)
  (Output ErrorCause
protoErrorout, Input ErrorCause
errorin) <- Buffer ErrorCause -> IO (Output ErrorCause, Input ErrorCause)
forall a. Buffer a -> IO (Output a, Input a)
spawn (Int -> Buffer ErrorCause
forall a. Int -> Buffer a
newest Int
1)
  (Output DBusSignal
allout, Input DBusSignal
allin) <- Buffer DBusSignal -> IO (Output DBusSignal, Input DBusSignal)
forall a. Buffer a -> IO (Output a, Input a)
spawn (DBusSignal -> Buffer DBusSignal
forall a. a -> Buffer a
latest DBusSignal
NoInfo)

  let realTrackout :: Output TrackIdentifier
realTrackout = (TrackIdentifier -> (TrackIdentifier, DBusSignal))
-> Output TrackIdentifier
-> Output DBusSignal
-> Output TrackIdentifier
forall a b c. (a -> (b, c)) -> Output b -> Output c -> Output a
forall (f :: * -> *) a b c.
Divisible f =>
(a -> (b, c)) -> f b -> f c -> f a
divide (\TrackIdentifier
a -> (TrackIdentifier
a, TrackIdentifier -> DBusSignal
Song TrackIdentifier
a)) Output TrackIdentifier
protoTrackout Output DBusSignal
allout
      realErrorout :: Output ErrorCause
realErrorout = (ErrorCause -> (ErrorCause, DBusSignal))
-> Output ErrorCause -> Output DBusSignal -> Output ErrorCause
forall a b c. (a -> (b, c)) -> Output b -> Output c -> Output a
forall (f :: * -> *) a b c.
Divisible f =>
(a -> (b, c)) -> f b -> f c -> f a
divide (\ErrorCause
a -> (ErrorCause
a, ErrorCause -> DBusSignal
Error ErrorCause
a)) Output ErrorCause
protoErrorout Output DBusSignal
allout
      singleProd :: Proxy a' a () DBusSignal IO ()
singleProd = Input DBusSignal -> Producer' DBusSignal IO ()
forall (m :: * -> *) a. MonadIO m => Input a -> Producer' a m ()
fromInput Input DBusSignal
allin Proxy a' a () DBusSignal IO ()
-> Proxy () DBusSignal () DBusSignal IO ()
-> Proxy a' a () DBusSignal IO ()
forall (m :: * -> *) a' a b r c' c.
Functor m =>
Proxy a' a () b m r -> Proxy () b c' c m r -> Proxy a' a c' c m r
>-> Int -> Proxy () DBusSignal () DBusSignal IO ()
forall (m :: * -> *) a. Functor m => Int -> Pipe a a m ()
PP.take Int
1

  (Input TrackIdentifier, Input ErrorCause,
 Producer DBusSignal IO (), Output TrackIdentifier,
 Output ErrorCause)
-> IO
     (Input TrackIdentifier, Input ErrorCause,
      Producer DBusSignal IO (), Output TrackIdentifier,
      Output ErrorCause)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Input TrackIdentifier, Input ErrorCause,
  Producer DBusSignal IO (), Output TrackIdentifier,
  Output ErrorCause)
 -> IO
      (Input TrackIdentifier, Input ErrorCause,
       Producer DBusSignal IO (), Output TrackIdentifier,
       Output ErrorCause))
-> (Input TrackIdentifier, Input ErrorCause,
    Producer DBusSignal IO (), Output TrackIdentifier,
    Output ErrorCause)
-> IO
     (Input TrackIdentifier, Input ErrorCause,
      Producer DBusSignal IO (), Output TrackIdentifier,
      Output ErrorCause)
forall a b. (a -> b) -> a -> b
$ (Input TrackIdentifier
trackin, Input ErrorCause
errorin, Producer DBusSignal IO ()
Producer' DBusSignal IO ()
singleProd, Output TrackIdentifier
realTrackout, Output ErrorCause
realErrorout)

addSuplArtist :: TVar (Maybe TrackSuplement) -> Pipe TrackIdentifier TrackIdentifier IO a
addSuplArtist :: forall a.
TVar (Maybe TrackSuplement)
-> Pipe TrackIdentifier TrackIdentifier IO a
addSuplArtist TVar (Maybe TrackSuplement)
svar = (TrackIdentifier -> IO TrackIdentifier)
-> Pipe TrackIdentifier TrackIdentifier IO a
forall (m :: * -> *) a b r. Monad m => (a -> m b) -> Pipe a b m r
PP.mapM TrackIdentifier -> IO TrackIdentifier
go
  where
    go :: TrackIdentifier -> IO TrackIdentifier
    go :: TrackIdentifier -> IO TrackIdentifier
go signal :: TrackIdentifier
signal@(Left TrackByPath
OnlyMissingArtist) =
      STM (Maybe TrackSuplement) -> IO (Maybe TrackSuplement)
forall a. STM a -> IO a
atomically (TVar (Maybe TrackSuplement) -> STM (Maybe TrackSuplement)
forall a. TVar a -> STM a
readTVar TVar (Maybe TrackSuplement)
svar)
        IO (Maybe TrackSuplement)
-> (Maybe TrackSuplement -> IO TrackIdentifier)
-> IO TrackIdentifier
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TrackIdentifier -> IO TrackIdentifier
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TrackIdentifier -> IO TrackIdentifier)
-> (Maybe TrackSuplement -> TrackIdentifier)
-> Maybe TrackSuplement
-> IO TrackIdentifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TrackIdentifier
-> (TrackSuplement -> TrackIdentifier)
-> Maybe TrackSuplement
-> TrackIdentifier
forall b a. b -> (a -> b) -> Maybe a -> b
maybe TrackIdentifier
signal ((TrackSuplement -> TrackIdentifier -> TrackIdentifier)
-> TrackIdentifier -> TrackSuplement -> TrackIdentifier
forall a b c. (a -> b -> c) -> b -> a -> c
flip TrackSuplement -> TrackIdentifier -> TrackIdentifier
suplementOnlyArtist TrackIdentifier
signal)
    go TrackIdentifier
other = TrackIdentifier -> IO TrackIdentifier
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TrackIdentifier
other