{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}

-- | This module provides functionality for decoding data from a toml
-- configuration file.
module Navi.Config.Toml
  ( ConfigToml (..),
  )
where

import Navi.Config.Types (LogLoc (..), Logging (..), NoteSystem (..))
import Navi.Prelude
import Navi.Services.Battery.Percentage.Toml (BatteryPercentageToml)
import Navi.Services.Battery.Status.Toml (BatteryStatusToml)
import Navi.Services.Custom.Multiple.Toml (MultipleToml)
import Navi.Services.Custom.Single.Toml (SingleToml)
import Navi.Services.Network.NetInterfaces.Toml (NetInterfacesToml)
import Navi.Utils (getFieldOptArrayOf)

-- | 'ConfigToml' holds the data that is defined in the configuration file.
data ConfigToml = MkConfigToml
  { ConfigToml -> Maybe Logging
logToml :: !(Maybe Logging),
    ConfigToml -> Maybe NoteSystem
noteSystemToml :: !(Maybe NoteSystem),
    ConfigToml -> [SingleToml]
singleToml :: ![SingleToml],
    ConfigToml -> [MultipleToml]
multipleToml :: ![MultipleToml],
    ConfigToml -> Maybe BatteryPercentageToml
batteryPercentageToml :: !(Maybe BatteryPercentageToml),
    ConfigToml -> Maybe BatteryStatusToml
batteryStatusToml :: !(Maybe BatteryStatusToml),
    ConfigToml -> [NetInterfacesToml]
netInterfacesToml :: ![NetInterfacesToml]
  }
  deriving stock (ConfigToml -> ConfigToml -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConfigToml -> ConfigToml -> Bool
$c/= :: ConfigToml -> ConfigToml -> Bool
== :: ConfigToml -> ConfigToml -> Bool
$c== :: ConfigToml -> ConfigToml -> Bool
Eq, Int -> ConfigToml -> ShowS
[ConfigToml] -> ShowS
ConfigToml -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ConfigToml] -> ShowS
$cshowList :: [ConfigToml] -> ShowS
show :: ConfigToml -> String
$cshow :: ConfigToml -> String
showsPrec :: Int -> ConfigToml -> ShowS
$cshowsPrec :: Int -> ConfigToml -> ShowS
Show)

makeFieldLabelsNoPrefix ''ConfigToml

-- | @since 0.1
instance DecodeTOML ConfigToml where
  tomlDecoder :: Decoder ConfigToml
tomlDecoder =
    Maybe Logging
-> Maybe NoteSystem
-> [SingleToml]
-> [MultipleToml]
-> Maybe BatteryPercentageToml
-> Maybe BatteryStatusToml
-> [NetInterfacesToml]
-> ConfigToml
MkConfigToml
      forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder (Maybe Logging)
logDecoderOpt
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder NoteSystem
noteSystemDecoder Text
"note-system"
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. DecodeTOML a => Text -> Decoder [a]
getFieldOptArrayOf Text
"single"
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. DecodeTOML a => Text -> Decoder [a]
getFieldOptArrayOf Text
"multiple"
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"battery-percentage"
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"battery-status"
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. DecodeTOML a => Text -> Decoder [a]
getFieldOptArrayOf Text
"net-interface"

logDecoderOpt :: Decoder (Maybe Logging)
logDecoderOpt :: Decoder (Maybe Logging)
logDecoderOpt = forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder Logging
logDecoder Text
"logging"

logDecoder :: Decoder Logging
logDecoder :: Decoder Logging
logDecoder =
  Maybe LogLevel -> Maybe LogLoc -> Logging
MkLogging
    forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder (Maybe LogLevel)
severityDecoderOpt
    forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe LogLoc)
locationDecoderOpt

severityDecoderOpt :: Decoder (Maybe LogLevel)
severityDecoderOpt :: Decoder (Maybe LogLevel)
severityDecoderOpt = forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder LogLevel
severityDecoder Text
"severity"

severityDecoder :: Decoder LogLevel
severityDecoder :: Decoder LogLevel
severityDecoder =
  forall a. DecodeTOML a => Decoder a
tomlDecoder forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Text
"debug" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure LogLevel
LevelDebug
    Text
"info" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure LogLevel
LevelInfo
    Text
"error" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure LogLevel
LevelError
    Text
bad -> forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ Text -> String
unpack forall a b. (a -> b) -> a -> b
$ Text
"Unsupported severity: " forall a. Semigroup a => a -> a -> a
<> Text
bad

locationDecoderOpt :: Decoder (Maybe LogLoc)
locationDecoderOpt :: Decoder (Maybe LogLoc)
locationDecoderOpt = forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder LogLoc
locationDecoder Text
"location"

locationDecoder :: Decoder LogLoc
locationDecoder :: Decoder LogLoc
locationDecoder =
  forall a. DecodeTOML a => Decoder a
tomlDecoder forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Text
"default" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure LogLoc
DefPath
    Text
"stdout" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure LogLoc
Stdout
    Text
f -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ String -> LogLoc
File forall a b. (a -> b) -> a -> b
$ Text -> String
unpack Text
f

noteSystemDecoder :: Decoder NoteSystem
noteSystemDecoder :: Decoder NoteSystem
noteSystemDecoder =
  forall a. DecodeTOML a => Decoder a
tomlDecoder forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Text
"dbus" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure NoteSystem
DBus
    Text
"notify-send" -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure NoteSystem
NotifySend
    Text
bad -> forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ Text -> String
unpack forall a b. (a -> b) -> a -> b
$ Text
"Unsupported NoteSystem: " forall a. Semigroup a => a -> a -> a
<> Text
bad