{-# LANGUAGE CPP #-}
module Navi.Effects.MonadSystemInfo
( MonadSystemInfo (..),
)
where
import Navi.Data.CommandResult (CommandResult)
import Navi.Data.CommandResultParser (CommandResultParser)
import Navi.Data.PollInterval (PollInterval)
import Navi.Event.Types (EventError (MkEventError, long, name, short))
import Navi.Prelude
import Navi.Services.Types
( ServiceType
( BatteryPercentage,
BatteryStatus,
Custom,
NetworkInterface
),
)
import Navi.Utils qualified as U
import Pythia qualified
import Pythia.Data.Command (Command)
import Pythia.Internal.ShellApp
( SimpleShell
( MkSimpleShell,
command,
isSupported,
parser
),
)
import Pythia.Internal.ShellApp qualified as ShellApp
class (Monad m) => MonadSystemInfo m where
query :: (HasCallStack) => ServiceType result -> m (result, Maybe PollInterval)
instance MonadSystemInfo IO where
query :: ServiceType result -> IO (result, Maybe PollInterval)
query :: forall result.
ServiceType result -> IO (result, Maybe PollInterval)
query = \case
BatteryPercentage BatteryApp
bp ->
Text
-> IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval)
forall a. Text -> IO a -> IO a
rethrowPythia Text
"Battery Percentage" (IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval))
-> IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval)
forall a b. (a -> b) -> a -> b
$ (,Maybe PollInterval
forall a. Maybe a
Nothing) (result -> (result, Maybe PollInterval))
-> IO result -> IO (result, Maybe PollInterval)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> BatteryApp -> IO Battery
forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadFileReader m, MonadPathReader m,
MonadTypedProcess m) =>
BatteryApp -> m Battery
Pythia.queryBattery BatteryApp
bp
BatteryStatus BatteryApp
bp ->
Text
-> IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval)
forall a. Text -> IO a -> IO a
rethrowPythia Text
"Battery Status" (IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval))
-> IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval)
forall a b. (a -> b) -> a -> b
$ (,Maybe PollInterval
forall a. Maybe a
Nothing) (BatteryStatus -> (BatteryStatus, Maybe PollInterval))
-> (Battery -> BatteryStatus)
-> Battery
-> (BatteryStatus, Maybe PollInterval)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Optic' A_Lens NoIx Battery BatteryStatus
-> Battery -> BatteryStatus
forall k (is :: IxList) s a.
Is k A_Getter =>
Optic' k is s a -> s -> a
view Optic' A_Lens NoIx Battery BatteryStatus
#status (Battery -> (result, Maybe PollInterval))
-> IO Battery -> IO (result, Maybe PollInterval)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> BatteryApp -> IO Battery
forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadFileReader m, MonadPathReader m,
MonadTypedProcess m) =>
BatteryApp -> m Battery
Pythia.queryBattery BatteryApp
bp
NetworkInterface Device
device NetInterfaceApp
cp ->
Text
-> IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval)
forall a. Text -> IO a -> IO a
rethrowPythia Text
"NetInterface" (IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval))
-> IO (result, Maybe PollInterval)
-> IO (result, Maybe PollInterval)
forall a b. (a -> b) -> a -> b
$ (,Maybe PollInterval
forall a. Maybe a
Nothing) (result -> (result, Maybe PollInterval))
-> IO result -> IO (result, Maybe PollInterval)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Device -> NetInterfaceApp -> IO NetInterface
forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m, MonadThrow m,
MonadTypedProcess m) =>
Device -> NetInterfaceApp -> m NetInterface
Pythia.queryNetInterface Device
device NetInterfaceApp
cp
Custom Command
cmd CommandResultParser
parser -> Text
-> IO (CommandResult, Maybe PollInterval)
-> IO (CommandResult, Maybe PollInterval)
forall a. Text -> IO a -> IO a
rethrowPythia Text
"Custom" (IO (CommandResult, Maybe PollInterval)
-> IO (CommandResult, Maybe PollInterval))
-> IO (CommandResult, Maybe PollInterval)
-> IO (CommandResult, Maybe PollInterval)
forall a b. (a -> b) -> a -> b
$ Command
-> CommandResultParser -> IO (CommandResult, Maybe PollInterval)
querySimple Command
cmd CommandResultParser
parser
rethrowPythia :: Text -> IO a -> IO a
rethrowPythia :: forall a. Text -> IO a -> IO a
rethrowPythia Text
n IO a
io =
IO a
io IO a -> (SomeException -> IO a) -> IO a
forall (m :: Type -> Type) a.
(HasCallStack, MonadCatch m) =>
m a -> (SomeException -> m a) -> m a
`catchSync` \SomeException
e ->
EventError -> IO a
forall e a. (HasCallStack, Exception e) => e -> IO a
forall (m :: Type -> Type) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM
(EventError -> IO a) -> EventError -> IO a
forall a b. (a -> b) -> a -> b
$ MkEventError
{ name :: Text
name = Text
n,
short :: Text
short = Text
"PythiaException",
long :: Text
long = String -> Text
packText (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ SomeException -> String
forall e. Exception e => e -> String
U.displayInner SomeException
e
}
instance (MonadSystemInfo m) => MonadSystemInfo (ReaderT e m) where
query :: forall result.
HasCallStack =>
ServiceType result -> ReaderT e m (result, Maybe PollInterval)
query = m (result, Maybe PollInterval)
-> ReaderT e m (result, Maybe PollInterval)
forall (m :: Type -> Type) a. Monad m => m a -> ReaderT e m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (result, Maybe PollInterval)
-> ReaderT e m (result, Maybe PollInterval))
-> (ServiceType result -> m (result, Maybe PollInterval))
-> ServiceType result
-> ReaderT e m (result, Maybe PollInterval)
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ServiceType result -> m (result, Maybe PollInterval)
forall result.
HasCallStack =>
ServiceType result -> m (result, Maybe PollInterval)
forall (m :: Type -> Type) result.
(MonadSystemInfo m, HasCallStack) =>
ServiceType result -> m (result, Maybe PollInterval)
query
{-# INLINEABLE query #-}
querySimple :: Command -> CommandResultParser -> IO (CommandResult, Maybe PollInterval)
querySimple :: Command
-> CommandResultParser -> IO (CommandResult, Maybe PollInterval)
querySimple Command
cmd CommandResultParser
parser = (\CommandResult
cr -> (CommandResult
cr, CommandResult
cr CommandResult
-> Optic' A_Lens NoIx CommandResult (Maybe PollInterval)
-> Maybe PollInterval
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx CommandResult (Maybe PollInterval)
#pollInterval)) (CommandResult -> (CommandResult, Maybe PollInterval))
-> IO CommandResult -> IO (CommandResult, Maybe PollInterval)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> SimpleShell IO EventError CommandResult -> IO CommandResult
forall (m :: Type -> Type) err result.
(Exception err, HasCallStack, MonadThrow m, MonadTypedProcess m) =>
SimpleShell m err result -> m result
ShellApp.runSimple SimpleShell IO EventError CommandResult
shellApp
where
shellApp :: SimpleShell IO EventError CommandResult
shellApp = Command
-> (Text -> Either EventError CommandResult)
-> SimpleShell IO EventError CommandResult
forall (f :: Type -> Type).
Applicative f =>
Command
-> (Text -> Either EventError CommandResult)
-> SimpleShell f EventError CommandResult
mkApp Command
cmd (CommandResultParser
parser CommandResultParser
-> Optic'
An_Iso
NoIx
CommandResultParser
(Text -> Either EventError CommandResult)
-> Text
-> Either EventError CommandResult
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
An_Iso
NoIx
CommandResultParser
(Text -> Either EventError CommandResult)
#unCommandResultParser)
mkApp ::
(Applicative f) =>
Command ->
(Text -> Either EventError CommandResult) ->
SimpleShell f EventError CommandResult
mkApp :: forall (f :: Type -> Type).
Applicative f =>
Command
-> (Text -> Either EventError CommandResult)
-> SimpleShell f EventError CommandResult
mkApp Command
cmd Text -> Either EventError CommandResult
parser =
MkSimpleShell
{ command :: Command
command = Command
cmd,
isSupported :: f Bool
isSupported = Bool -> f Bool
forall a. a -> f a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Bool
True,
Text -> Either EventError CommandResult
parser :: Text -> Either EventError CommandResult
parser :: Text -> Either EventError CommandResult
parser
}