module Mpv.Socket where import qualified Network.Socket as Socket import Network.Socket (SockAddr (SockAddrUnix), Socket) import Path (Abs, File, Path, toFilePath) import Polysemy.Conc (retryingWithError) import Polysemy.Time (MilliSeconds (MilliSeconds), Seconds (Seconds)) import qualified Mpv.Data.MpvError as MpvError import Mpv.Data.MpvError (MpvError) unixSocket :: Members [Error MpvError, Embed IO] r => Sem r Socket unixSocket :: forall (r :: [(* -> *) -> * -> *]). Members '[Error MpvError, Embed IO] r => Sem r Socket unixSocket = forall exc err (r :: [(* -> *) -> * -> *]) a. (Exception exc, Member (Error err) r, Member (Embed IO) r) => (exc -> err) -> IO a -> Sem r a fromExceptionVia @SomeException (Text -> MpvError MpvError.Fatal (Text -> MpvError) -> (SomeException -> Text) -> SomeException -> MpvError forall b c a. (b -> c) -> (a -> b) -> a -> c . SomeException -> Text forall b a. (Show a, IsString b) => a -> b show) (Family -> SocketType -> ProtocolNumber -> IO Socket Socket.socket Family Socket.AF_UNIX SocketType Socket.Stream ProtocolNumber 0) connectSocket :: Member (Embed IO) r => Path Abs File -> Socket -> Sem r (Either Text ()) connectSocket :: forall (r :: [(* -> *) -> * -> *]). Member (Embed IO) r => Path Abs File -> Socket -> Sem r (Either Text ()) connectSocket Path Abs File path Socket socket = IO () -> Sem r (Either Text ()) forall (r :: [(* -> *) -> * -> *]) a. Member (Embed IO) r => IO a -> Sem r (Either Text a) tryAny (Socket -> SockAddr -> IO () Socket.connect Socket socket (String -> SockAddr SockAddrUnix (Path Abs File -> String forall b t. Path b t -> String toFilePath Path Abs File path))) acquireSocket :: Members [Error MpvError, Race, Time t d, Embed IO] r => Path Abs File -> Sem r Socket acquireSocket :: forall t d (r :: [(* -> *) -> * -> *]). Members '[Error MpvError, Race, Time t d, Embed IO] r => Path Abs File -> Sem r Socket acquireSocket Path Abs File path = do Socket socket <- Sem r Socket forall (r :: [(* -> *) -> * -> *]). Members '[Error MpvError, Embed IO] r => Sem r Socket unixSocket Seconds -> MilliSeconds -> Sem r (Either Text ()) -> Sem r (Maybe (Either Text ())) forall e w u t d (r :: [(* -> *) -> * -> *]) a. (TimeUnit w, TimeUnit u, Members '[Race, Time t d, Embed IO] r) => w -> u -> Sem r (Either e a) -> Sem r (Maybe (Either e a)) retryingWithError (Int64 -> Seconds Seconds Int64 5) (Int64 -> MilliSeconds MilliSeconds Int64 100) (Path Abs File -> Socket -> Sem r (Either Text ()) forall (r :: [(* -> *) -> * -> *]). Member (Embed IO) r => Path Abs File -> Socket -> Sem r (Either Text ()) connectSocket Path Abs File path Socket socket) Sem r (Maybe (Either Text ())) -> (Maybe (Either Text ()) -> Sem r Socket) -> Sem r Socket forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b >>= \case Just (Right ()) -> Socket -> Sem r Socket forall (f :: * -> *) a. Applicative f => a -> f a pure Socket socket Just (Left Text err) -> MpvError -> Sem r Socket forall e (r :: [(* -> *) -> * -> *]) a. MemberWithError (Error e) r => e -> Sem r a throw (Text -> MpvError MpvError.Fatal Text err) Maybe (Either Text ()) Nothing -> MpvError -> Sem r Socket forall e (r :: [(* -> *) -> * -> *]) a. MemberWithError (Error e) r => e -> Sem r a throw (Text -> MpvError MpvError.Fatal Text "socket connect timed out") releaseSocket :: Member (Embed IO) r => Either MpvError Socket -> Sem r () releaseSocket :: forall (r :: [(* -> *) -> * -> *]). Member (Embed IO) r => Either MpvError Socket -> Sem r () releaseSocket = \case Right Socket sock -> Sem r (Either Text ()) -> Sem r () forall (f :: * -> *) a. Functor f => f a -> f () void (IO () -> Sem r (Either Text ()) forall (r :: [(* -> *) -> * -> *]) a. Member (Embed IO) r => IO a -> Sem r (Either Text a) tryAny (Socket -> IO () Socket.close Socket sock)) Left MpvError _ -> Sem r () forall (f :: * -> *). Applicative f => f () unit withSocket :: Members [Resource, Race, Time t d, Embed IO] r => Path Abs File -> (Either MpvError Socket -> Sem r a) -> Sem r a withSocket :: forall t d (r :: [(* -> *) -> * -> *]) a. Members '[Resource, Race, Time t d, Embed IO] r => Path Abs File -> (Either MpvError Socket -> Sem r a) -> Sem r a withSocket Path Abs File path = Sem r (Either MpvError Socket) -> (Either MpvError Socket -> Sem r ()) -> (Either MpvError Socket -> Sem r a) -> Sem r a forall (r :: [(* -> *) -> * -> *]) a c b. MemberWithError Resource r => Sem r a -> (a -> Sem r c) -> (a -> Sem r b) -> Sem r b bracket (Sem (Error MpvError : r) Socket -> Sem r (Either MpvError Socket) forall e (r :: [(* -> *) -> * -> *]) a. Sem (Error e : r) a -> Sem r (Either e a) runError (Path Abs File -> Sem (Error MpvError : r) Socket forall t d (r :: [(* -> *) -> * -> *]). Members '[Error MpvError, Race, Time t d, Embed IO] r => Path Abs File -> Sem r Socket acquireSocket Path Abs File path)) Either MpvError Socket -> Sem r () forall (r :: [(* -> *) -> * -> *]). Member (Embed IO) r => Either MpvError Socket -> Sem r () releaseSocket