{-# LANGUAGE UndecidableInstances #-}

-- | This module provides the core types describing the battery.
--
-- @since 0.1
module Pythia.Services.Battery.Types
  ( -- * Configuration
    BatteryApp (..),

    -- * Battery Fields
    BatteryStatus (..),
    Battery (..),

    -- * Optics
    _BatteryAppAcpi,
    _BatteryAppSysFs,
    _BatteryAppUPower,
    _Charging,
    _Discharging,
    _Full,
    _Pending,
  )
where

import Pythia.Data.Percentage (Percentage)
import Pythia.Prelude

-- $setup
-- >>> import Pythia.Prelude

-- | Determines how we should query the system for battery state information.
--
-- @since 0.1
type BatteryApp :: Type
data BatteryApp
  = -- | Uses the sysfs interface i.e. /sys.
    --
    -- @since 0.1
    BatteryAppSysFs
  | -- | Uses the ACPI utility.
    --
    -- @since 0.1
    BatteryAppAcpi
  | -- | Uses the UPower utility.
    --
    -- @since 0.1
    BatteryAppUPower
  deriving stock
    ( -- | @since 0.1
      BatteryApp
BatteryApp -> BatteryApp -> Bounded BatteryApp
forall a. a -> a -> Bounded a
$cminBound :: BatteryApp
minBound :: BatteryApp
$cmaxBound :: BatteryApp
maxBound :: BatteryApp
Bounded,
      -- | @since 0.1
      Int -> BatteryApp
BatteryApp -> Int
BatteryApp -> [BatteryApp]
BatteryApp -> BatteryApp
BatteryApp -> BatteryApp -> [BatteryApp]
BatteryApp -> BatteryApp -> BatteryApp -> [BatteryApp]
(BatteryApp -> BatteryApp)
-> (BatteryApp -> BatteryApp)
-> (Int -> BatteryApp)
-> (BatteryApp -> Int)
-> (BatteryApp -> [BatteryApp])
-> (BatteryApp -> BatteryApp -> [BatteryApp])
-> (BatteryApp -> BatteryApp -> [BatteryApp])
-> (BatteryApp -> BatteryApp -> BatteryApp -> [BatteryApp])
-> Enum BatteryApp
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: BatteryApp -> BatteryApp
succ :: BatteryApp -> BatteryApp
$cpred :: BatteryApp -> BatteryApp
pred :: BatteryApp -> BatteryApp
$ctoEnum :: Int -> BatteryApp
toEnum :: Int -> BatteryApp
$cfromEnum :: BatteryApp -> Int
fromEnum :: BatteryApp -> Int
$cenumFrom :: BatteryApp -> [BatteryApp]
enumFrom :: BatteryApp -> [BatteryApp]
$cenumFromThen :: BatteryApp -> BatteryApp -> [BatteryApp]
enumFromThen :: BatteryApp -> BatteryApp -> [BatteryApp]
$cenumFromTo :: BatteryApp -> BatteryApp -> [BatteryApp]
enumFromTo :: BatteryApp -> BatteryApp -> [BatteryApp]
$cenumFromThenTo :: BatteryApp -> BatteryApp -> BatteryApp -> [BatteryApp]
enumFromThenTo :: BatteryApp -> BatteryApp -> BatteryApp -> [BatteryApp]
Enum,
      -- | @since 0.1
      BatteryApp -> BatteryApp -> Bool
(BatteryApp -> BatteryApp -> Bool)
-> (BatteryApp -> BatteryApp -> Bool) -> Eq BatteryApp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BatteryApp -> BatteryApp -> Bool
== :: BatteryApp -> BatteryApp -> Bool
$c/= :: BatteryApp -> BatteryApp -> Bool
/= :: BatteryApp -> BatteryApp -> Bool
Eq,
      -- | @since 0.1
      (forall x. BatteryApp -> Rep BatteryApp x)
-> (forall x. Rep BatteryApp x -> BatteryApp) -> Generic BatteryApp
forall x. Rep BatteryApp x -> BatteryApp
forall x. BatteryApp -> Rep BatteryApp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. BatteryApp -> Rep BatteryApp x
from :: forall x. BatteryApp -> Rep BatteryApp x
$cto :: forall x. Rep BatteryApp x -> BatteryApp
to :: forall x. Rep BatteryApp x -> BatteryApp
Generic,
      -- | @since 0.1
      Eq BatteryApp
Eq BatteryApp =>
(BatteryApp -> BatteryApp -> Ordering)
-> (BatteryApp -> BatteryApp -> Bool)
-> (BatteryApp -> BatteryApp -> Bool)
-> (BatteryApp -> BatteryApp -> Bool)
-> (BatteryApp -> BatteryApp -> Bool)
-> (BatteryApp -> BatteryApp -> BatteryApp)
-> (BatteryApp -> BatteryApp -> BatteryApp)
-> Ord BatteryApp
BatteryApp -> BatteryApp -> Bool
BatteryApp -> BatteryApp -> Ordering
BatteryApp -> BatteryApp -> BatteryApp
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: BatteryApp -> BatteryApp -> Ordering
compare :: BatteryApp -> BatteryApp -> Ordering
$c< :: BatteryApp -> BatteryApp -> Bool
< :: BatteryApp -> BatteryApp -> Bool
$c<= :: BatteryApp -> BatteryApp -> Bool
<= :: BatteryApp -> BatteryApp -> Bool
$c> :: BatteryApp -> BatteryApp -> Bool
> :: BatteryApp -> BatteryApp -> Bool
$c>= :: BatteryApp -> BatteryApp -> Bool
>= :: BatteryApp -> BatteryApp -> Bool
$cmax :: BatteryApp -> BatteryApp -> BatteryApp
max :: BatteryApp -> BatteryApp -> BatteryApp
$cmin :: BatteryApp -> BatteryApp -> BatteryApp
min :: BatteryApp -> BatteryApp -> BatteryApp
Ord,
      -- | @since 0.1
      Int -> BatteryApp -> ShowS
[BatteryApp] -> ShowS
BatteryApp -> [Char]
(Int -> BatteryApp -> ShowS)
-> (BatteryApp -> [Char])
-> ([BatteryApp] -> ShowS)
-> Show BatteryApp
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BatteryApp -> ShowS
showsPrec :: Int -> BatteryApp -> ShowS
$cshow :: BatteryApp -> [Char]
show :: BatteryApp -> [Char]
$cshowList :: [BatteryApp] -> ShowS
showList :: [BatteryApp] -> ShowS
Show
    )
  deriving anyclass
    ( -- | @since 0.1.0.0
      BatteryApp -> ()
(BatteryApp -> ()) -> NFData BatteryApp
forall a. (a -> ()) -> NFData a
$crnf :: BatteryApp -> ()
rnf :: BatteryApp -> ()
NFData
    )

-- | @since 0.1
_BatteryAppSysFs :: Prism' BatteryApp ()
_BatteryAppSysFs :: Prism' BatteryApp ()
_BatteryAppSysFs =
  (() -> BatteryApp)
-> (BatteryApp -> Either BatteryApp ()) -> Prism' BatteryApp ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryApp -> () -> BatteryApp
forall a b. a -> b -> a
const BatteryApp
BatteryAppSysFs)
    ( \BatteryApp
x -> case BatteryApp
x of
        BatteryApp
BatteryAppSysFs -> () -> Either BatteryApp ()
forall a b. b -> Either a b
Right ()
        BatteryApp
_ -> BatteryApp -> Either BatteryApp ()
forall a b. a -> Either a b
Left BatteryApp
x
    )
{-# INLINE _BatteryAppSysFs #-}

-- | @since 0.1
_BatteryAppAcpi :: Prism' BatteryApp ()
_BatteryAppAcpi :: Prism' BatteryApp ()
_BatteryAppAcpi =
  (() -> BatteryApp)
-> (BatteryApp -> Either BatteryApp ()) -> Prism' BatteryApp ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryApp -> () -> BatteryApp
forall a b. a -> b -> a
const BatteryApp
BatteryAppAcpi)
    ( \BatteryApp
x -> case BatteryApp
x of
        BatteryApp
BatteryAppAcpi -> () -> Either BatteryApp ()
forall a b. b -> Either a b
Right ()
        BatteryApp
_ -> BatteryApp -> Either BatteryApp ()
forall a b. a -> Either a b
Left BatteryApp
x
    )
{-# INLINE _BatteryAppAcpi #-}

-- | @since 0.1
_BatteryAppUPower :: Prism' BatteryApp ()
_BatteryAppUPower :: Prism' BatteryApp ()
_BatteryAppUPower =
  (() -> BatteryApp)
-> (BatteryApp -> Either BatteryApp ()) -> Prism' BatteryApp ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryApp -> () -> BatteryApp
forall a b. a -> b -> a
const BatteryApp
BatteryAppUPower)
    ( \BatteryApp
x -> case BatteryApp
x of
        BatteryApp
BatteryAppUPower -> () -> Either BatteryApp ()
forall a b. b -> Either a b
Right ()
        BatteryApp
_ -> BatteryApp -> Either BatteryApp ()
forall a b. a -> Either a b
Left BatteryApp
x
    )
{-# INLINE _BatteryAppUPower #-}

-- | Represents battery charging status.
--
-- @since 0.1
type BatteryStatus :: Type
data BatteryStatus
  = -- | @since 0.1
    Charging
  | -- | @since 0.1
    Discharging
  | -- | @since 0.1
    Full
  | -- | @since 0.1
    Pending
  deriving stock
    ( -- | @since 0.1
      BatteryStatus -> BatteryStatus -> Bool
(BatteryStatus -> BatteryStatus -> Bool)
-> (BatteryStatus -> BatteryStatus -> Bool) -> Eq BatteryStatus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BatteryStatus -> BatteryStatus -> Bool
== :: BatteryStatus -> BatteryStatus -> Bool
$c/= :: BatteryStatus -> BatteryStatus -> Bool
/= :: BatteryStatus -> BatteryStatus -> Bool
Eq,
      -- | @since 0.1
      (forall x. BatteryStatus -> Rep BatteryStatus x)
-> (forall x. Rep BatteryStatus x -> BatteryStatus)
-> Generic BatteryStatus
forall x. Rep BatteryStatus x -> BatteryStatus
forall x. BatteryStatus -> Rep BatteryStatus x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. BatteryStatus -> Rep BatteryStatus x
from :: forall x. BatteryStatus -> Rep BatteryStatus x
$cto :: forall x. Rep BatteryStatus x -> BatteryStatus
to :: forall x. Rep BatteryStatus x -> BatteryStatus
Generic,
      -- | @since 0.1
      Int -> BatteryStatus -> ShowS
[BatteryStatus] -> ShowS
BatteryStatus -> [Char]
(Int -> BatteryStatus -> ShowS)
-> (BatteryStatus -> [Char])
-> ([BatteryStatus] -> ShowS)
-> Show BatteryStatus
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BatteryStatus -> ShowS
showsPrec :: Int -> BatteryStatus -> ShowS
$cshow :: BatteryStatus -> [Char]
show :: BatteryStatus -> [Char]
$cshowList :: [BatteryStatus] -> ShowS
showList :: [BatteryStatus] -> ShowS
Show
    )
  deriving anyclass
    ( -- | @since 0.1
      BatteryStatus -> ()
(BatteryStatus -> ()) -> NFData BatteryStatus
forall a. (a -> ()) -> NFData a
$crnf :: BatteryStatus -> ()
rnf :: BatteryStatus -> ()
NFData
    )

-- | @since 0.1
_Charging :: Prism' BatteryStatus ()
_Charging :: Prism' BatteryStatus ()
_Charging =
  (() -> BatteryStatus)
-> (BatteryStatus -> Either BatteryStatus ())
-> Prism' BatteryStatus ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryStatus -> () -> BatteryStatus
forall a b. a -> b -> a
const BatteryStatus
Charging)
    ( \BatteryStatus
x -> case BatteryStatus
x of
        BatteryStatus
Charging -> () -> Either BatteryStatus ()
forall a b. b -> Either a b
Right ()
        BatteryStatus
_ -> BatteryStatus -> Either BatteryStatus ()
forall a b. a -> Either a b
Left BatteryStatus
x
    )
{-# INLINE _Charging #-}

-- | @since 0.1
_Discharging :: Prism' BatteryStatus ()
_Discharging :: Prism' BatteryStatus ()
_Discharging =
  (() -> BatteryStatus)
-> (BatteryStatus -> Either BatteryStatus ())
-> Prism' BatteryStatus ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryStatus -> () -> BatteryStatus
forall a b. a -> b -> a
const BatteryStatus
Discharging)
    ( \BatteryStatus
x -> case BatteryStatus
x of
        BatteryStatus
Discharging -> () -> Either BatteryStatus ()
forall a b. b -> Either a b
Right ()
        BatteryStatus
_ -> BatteryStatus -> Either BatteryStatus ()
forall a b. a -> Either a b
Left BatteryStatus
x
    )
{-# INLINE _Discharging #-}

-- | @since 0.1
_Full :: Prism' BatteryStatus ()
_Full :: Prism' BatteryStatus ()
_Full =
  (() -> BatteryStatus)
-> (BatteryStatus -> Either BatteryStatus ())
-> Prism' BatteryStatus ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryStatus -> () -> BatteryStatus
forall a b. a -> b -> a
const BatteryStatus
Full)
    ( \BatteryStatus
x -> case BatteryStatus
x of
        BatteryStatus
Full -> () -> Either BatteryStatus ()
forall a b. b -> Either a b
Right ()
        BatteryStatus
_ -> BatteryStatus -> Either BatteryStatus ()
forall a b. a -> Either a b
Left BatteryStatus
x
    )
{-# INLINE _Full #-}

-- | @since 0.1
_Pending :: Prism' BatteryStatus ()
_Pending :: Prism' BatteryStatus ()
_Pending =
  (() -> BatteryStatus)
-> (BatteryStatus -> Either BatteryStatus ())
-> Prism' BatteryStatus ()
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
    (BatteryStatus -> () -> BatteryStatus
forall a b. a -> b -> a
const BatteryStatus
Pending)
    ( \BatteryStatus
x -> case BatteryStatus
x of
        BatteryStatus
Pending -> () -> Either BatteryStatus ()
forall a b. b -> Either a b
Right ()
        BatteryStatus
_ -> BatteryStatus -> Either BatteryStatus ()
forall a b. a -> Either a b
Left BatteryStatus
x
    )
{-# INLINE _Pending #-}

-- | @since 0.1
instance Display BatteryStatus where
  displayBuilder :: BatteryStatus -> Builder
displayBuilder BatteryStatus
Charging = Builder
"Charging"
  displayBuilder BatteryStatus
Discharging = Builder
"Discharging"
  displayBuilder BatteryStatus
Full = Builder
"Full"
  displayBuilder BatteryStatus
Pending = Builder
"Pending"

-- | Full battery state, including percentage and status data.
--
-- @since 0.1
type Battery :: Type
data Battery = MkBattery
  { -- | @since 0.1
    Battery -> Percentage
percentage :: Percentage,
    -- | @since 0.1
    Battery -> BatteryStatus
status :: BatteryStatus
  }
  deriving stock
    ( -- | @since 0.1
      Battery -> Battery -> Bool
(Battery -> Battery -> Bool)
-> (Battery -> Battery -> Bool) -> Eq Battery
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Battery -> Battery -> Bool
== :: Battery -> Battery -> Bool
$c/= :: Battery -> Battery -> Bool
/= :: Battery -> Battery -> Bool
Eq,
      -- | @since 0.1
      (forall x. Battery -> Rep Battery x)
-> (forall x. Rep Battery x -> Battery) -> Generic Battery
forall x. Rep Battery x -> Battery
forall x. Battery -> Rep Battery x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Battery -> Rep Battery x
from :: forall x. Battery -> Rep Battery x
$cto :: forall x. Rep Battery x -> Battery
to :: forall x. Rep Battery x -> Battery
Generic,
      -- | @since 0.1
      Int -> Battery -> ShowS
[Battery] -> ShowS
Battery -> [Char]
(Int -> Battery -> ShowS)
-> (Battery -> [Char]) -> ([Battery] -> ShowS) -> Show Battery
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Battery -> ShowS
showsPrec :: Int -> Battery -> ShowS
$cshow :: Battery -> [Char]
show :: Battery -> [Char]
$cshowList :: [Battery] -> ShowS
showList :: [Battery] -> ShowS
Show
    )
  deriving anyclass
    ( -- | @since 0.1
      Battery -> ()
(Battery -> ()) -> NFData Battery
forall a. (a -> ()) -> NFData a
$crnf :: Battery -> ()
rnf :: Battery -> ()
NFData
    )

-- | @since 0.1
instance
  (k ~ A_Lens, a ~ Percentage, b ~ Percentage) =>
  LabelOptic "percentage" k Battery Battery a b
  where
  labelOptic :: Optic k NoIx Battery Battery a b
labelOptic = LensVL Battery Battery a b -> Lens Battery Battery a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL (LensVL Battery Battery a b -> Lens Battery Battery a b)
-> LensVL Battery Battery a b -> Lens Battery Battery a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkBattery Percentage
_percentage BatteryStatus
_status) ->
    (Percentage -> Battery) -> f Percentage -> f Battery
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Percentage -> BatteryStatus -> Battery
`MkBattery` BatteryStatus
_status) (a -> f b
f a
Percentage
_percentage)
  {-# INLINE labelOptic #-}

-- | @since 0.1
instance
  (k ~ A_Lens, a ~ BatteryStatus, b ~ BatteryStatus) =>
  LabelOptic "status" k Battery Battery a b
  where
  labelOptic :: Optic k NoIx Battery Battery a b
labelOptic = LensVL Battery Battery a b -> Lens Battery Battery a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL (LensVL Battery Battery a b -> Lens Battery Battery a b)
-> LensVL Battery Battery a b -> Lens Battery Battery a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkBattery Percentage
_percentage BatteryStatus
_status) ->
    (BatteryStatus -> Battery) -> f BatteryStatus -> f Battery
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Percentage -> BatteryStatus -> Battery
MkBattery Percentage
_percentage) (a -> f b
f a
BatteryStatus
_status)
  {-# INLINE labelOptic #-}

-- | @since 0.1
instance Display Battery where
  displayBuilder :: Battery -> Builder
displayBuilder Battery
bs =
    [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat
      [ Builder
status,
        Builder
": ",
        Builder
percentage
      ]
    where
      status :: Builder
status = BatteryStatus -> Builder
forall a. Display a => a -> Builder
displayBuilder (BatteryStatus -> Builder) -> BatteryStatus -> Builder
forall a b. (a -> b) -> a -> b
$ Battery
bs Battery
-> Optic' A_Lens NoIx Battery BatteryStatus -> BatteryStatus
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx Battery BatteryStatus
#status
      percentage :: Builder
percentage = Percentage -> Builder
forall a. Display a => a -> Builder
displayBuilder (Percentage -> Builder) -> Percentage -> Builder
forall a b. (a -> b) -> a -> b
$ Battery
bs Battery -> Optic' A_Lens NoIx Battery Percentage -> Percentage
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx Battery Percentage
#percentage