{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE UndecidableInstances #-}

module Shrun.Configuration.Data.FileLogging
  ( FileLogInitP (..),
    FileLogOpened (..),
    FileLoggingP (..),
    FileLoggingArgs,
    FileLoggingToml,
    FileLoggingMerged,
    FileLoggingEnv,
    DeleteOnSuccessSwitch (..),
    FileLogMultiSwitch (..),
    mergeFileLogging,
    withFileLoggingEnv,

    -- * Misc
    createMultiLogFile,
  )
where

import Data.Bytes
  ( FloatingFormatter (MkFloatingFormatter),
    Normalize (normalize),
    formatSized,
    sizedFormatterNatural,
  )
import Data.Text qualified as T
import Effects.FileSystem.HandleWriter (MonadHandleWriter (withBinaryFile), die)
import Effects.FileSystem.PathReader qualified as PR
import Effects.FileSystem.PathWriter (MonadPathWriter (createDirectoryIfMissing))
import Effects.System.Posix.Files (PathType (PathTypeFile))
import Effects.System.Posix.Files qualified as PosixFiles
import FileSystem.PathType qualified as PT
import Shrun.Command.Types (CommandP1)
import Shrun.Configuration.Data.ConfigPhase
  ( ConfigPhase
      ( ConfigPhaseArgs,
        ConfigPhaseEnv,
        ConfigPhaseMerged,
        ConfigPhaseToml
      ),
    ConfigPhaseDisabledMaybeF,
    ConfigPhaseF,
    LineTruncF,
    SwitchF,
    parseSwitch,
  )
import Shrun.Configuration.Data.FileLogging.FileMode (FileMode (FileModeRename))
import Shrun.Configuration.Data.FileLogging.FileMode qualified as FileMode
import Shrun.Configuration.Data.FileLogging.FilePathDefault
  ( FilePathDefault
      ( FPDefault,
        FPManual
      ),
  )
import Shrun.Configuration.Data.FileLogging.FileSizeMode
  ( FileSizeMode
      ( FileSizeModeDelete,
        FileSizeModeNothing,
        FileSizeModeWarn
      ),
  )
import Shrun.Configuration.Data.StripControl (FileLogStripControl)
import Shrun.Configuration.Data.Truncation
  ( DetectResult,
    TruncRegion (TruncCommandName),
    Truncation,
    decodeCommandNameTrunc,
    decodeLineTrunc,
    mergeLineTrunc,
  )
import Shrun.Configuration.Data.WithDisabled (WithDisabled, (<|?|>))
import Shrun.Configuration.Default (Default (def), (<.>))
import Shrun.Logging.Types (FileLog)
import Shrun.Prelude
import Shrun.Utils qualified as Utils
import System.OsPath qualified as OsPath
import System.OsString.Internal.Types (OsString (OsString))

-- | Switch for deleting the log file upon success.
newtype DeleteOnSuccessSwitch = MkDeleteOnSuccessSwitch Bool
  deriving stock (DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool
(DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool)
-> (DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool)
-> Eq DeleteOnSuccessSwitch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool
== :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool
$c/= :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool
/= :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch -> Bool
Eq, Int -> DeleteOnSuccessSwitch -> ShowS
[DeleteOnSuccessSwitch] -> ShowS
DeleteOnSuccessSwitch -> String
(Int -> DeleteOnSuccessSwitch -> ShowS)
-> (DeleteOnSuccessSwitch -> String)
-> ([DeleteOnSuccessSwitch] -> ShowS)
-> Show DeleteOnSuccessSwitch
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DeleteOnSuccessSwitch -> ShowS
showsPrec :: Int -> DeleteOnSuccessSwitch -> ShowS
$cshow :: DeleteOnSuccessSwitch -> String
show :: DeleteOnSuccessSwitch -> String
$cshowList :: [DeleteOnSuccessSwitch] -> ShowS
showList :: [DeleteOnSuccessSwitch] -> ShowS
Show)
  deriving newtype (DeleteOnSuccessSwitch
DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch -> Bounded DeleteOnSuccessSwitch
forall a. a -> a -> Bounded a
$cminBound :: DeleteOnSuccessSwitch
minBound :: DeleteOnSuccessSwitch
$cmaxBound :: DeleteOnSuccessSwitch
maxBound :: DeleteOnSuccessSwitch
Bounded, Int -> DeleteOnSuccessSwitch
DeleteOnSuccessSwitch -> Int
DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch
DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
-> [DeleteOnSuccessSwitch]
(DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch)
-> (DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch)
-> (Int -> DeleteOnSuccessSwitch)
-> (DeleteOnSuccessSwitch -> Int)
-> (DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch])
-> (DeleteOnSuccessSwitch
    -> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch])
-> (DeleteOnSuccessSwitch
    -> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch])
-> (DeleteOnSuccessSwitch
    -> DeleteOnSuccessSwitch
    -> DeleteOnSuccessSwitch
    -> [DeleteOnSuccessSwitch])
-> Enum DeleteOnSuccessSwitch
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 :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch
succ :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch
$cpred :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch
pred :: DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch
$ctoEnum :: Int -> DeleteOnSuccessSwitch
toEnum :: Int -> DeleteOnSuccessSwitch
$cfromEnum :: DeleteOnSuccessSwitch -> Int
fromEnum :: DeleteOnSuccessSwitch -> Int
$cenumFrom :: DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
enumFrom :: DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
$cenumFromThen :: DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
enumFromThen :: DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
$cenumFromTo :: DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
enumFromTo :: DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch -> [DeleteOnSuccessSwitch]
$cenumFromThenTo :: DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
-> [DeleteOnSuccessSwitch]
enumFromThenTo :: DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
-> [DeleteOnSuccessSwitch]
Enum)
  deriving ((forall ann. DeleteOnSuccessSwitch -> Doc ann)
-> (forall ann. [DeleteOnSuccessSwitch] -> Doc ann)
-> Pretty DeleteOnSuccessSwitch
forall ann. [DeleteOnSuccessSwitch] -> Doc ann
forall ann. DeleteOnSuccessSwitch -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
$cpretty :: forall ann. DeleteOnSuccessSwitch -> Doc ann
pretty :: forall ann. DeleteOnSuccessSwitch -> Doc ann
$cprettyList :: forall ann. [DeleteOnSuccessSwitch] -> Doc ann
prettyList :: forall ann. [DeleteOnSuccessSwitch] -> Doc ann
Pretty) via PrettySwitch

instance Default DeleteOnSuccessSwitch where
  def :: DeleteOnSuccessSwitch
def = Bool -> DeleteOnSuccessSwitch
MkDeleteOnSuccessSwitch Bool
False

instance DecodeTOML DeleteOnSuccessSwitch where
  tomlDecoder :: Decoder DeleteOnSuccessSwitch
tomlDecoder = Bool -> DeleteOnSuccessSwitch
MkDeleteOnSuccessSwitch (Bool -> DeleteOnSuccessSwitch)
-> Decoder Bool -> Decoder DeleteOnSuccessSwitch
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Decoder Text
forall a. DecodeTOML a => Decoder a
tomlDecoder Decoder Text -> (Text -> Decoder Bool) -> Decoder Bool
forall a b. Decoder a -> (a -> Decoder b) -> Decoder b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Decoder Bool
forall (m :: Type -> Type). MonadFail m => Text -> m Bool
parseSwitch)

instance
  (k ~ An_Iso, a ~ Bool, b ~ Bool) =>
  LabelOptic
    "unDeleteOnSuccessSwitch"
    k
    DeleteOnSuccessSwitch
    DeleteOnSuccessSwitch
    a
    b
  where
  labelOptic :: Optic k NoIx DeleteOnSuccessSwitch DeleteOnSuccessSwitch a b
labelOptic = (DeleteOnSuccessSwitch -> a)
-> (b -> DeleteOnSuccessSwitch)
-> Iso DeleteOnSuccessSwitch DeleteOnSuccessSwitch a b
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(MkDeleteOnSuccessSwitch Bool
b) -> a
Bool
b) b -> DeleteOnSuccessSwitch
Bool -> DeleteOnSuccessSwitch
MkDeleteOnSuccessSwitch
  {-# INLINE labelOptic #-}

-- | Switch for logging to multiple files.
newtype FileLogMultiSwitch = MkFileLogMultiSwitch Bool
  deriving stock (FileLogMultiSwitch -> FileLogMultiSwitch -> Bool
(FileLogMultiSwitch -> FileLogMultiSwitch -> Bool)
-> (FileLogMultiSwitch -> FileLogMultiSwitch -> Bool)
-> Eq FileLogMultiSwitch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FileLogMultiSwitch -> FileLogMultiSwitch -> Bool
== :: FileLogMultiSwitch -> FileLogMultiSwitch -> Bool
$c/= :: FileLogMultiSwitch -> FileLogMultiSwitch -> Bool
/= :: FileLogMultiSwitch -> FileLogMultiSwitch -> Bool
Eq, Int -> FileLogMultiSwitch -> ShowS
[FileLogMultiSwitch] -> ShowS
FileLogMultiSwitch -> String
(Int -> FileLogMultiSwitch -> ShowS)
-> (FileLogMultiSwitch -> String)
-> ([FileLogMultiSwitch] -> ShowS)
-> Show FileLogMultiSwitch
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> FileLogMultiSwitch -> ShowS
showsPrec :: Int -> FileLogMultiSwitch -> ShowS
$cshow :: FileLogMultiSwitch -> String
show :: FileLogMultiSwitch -> String
$cshowList :: [FileLogMultiSwitch] -> ShowS
showList :: [FileLogMultiSwitch] -> ShowS
Show)
  deriving newtype (FileLogMultiSwitch
FileLogMultiSwitch
-> FileLogMultiSwitch -> Bounded FileLogMultiSwitch
forall a. a -> a -> Bounded a
$cminBound :: FileLogMultiSwitch
minBound :: FileLogMultiSwitch
$cmaxBound :: FileLogMultiSwitch
maxBound :: FileLogMultiSwitch
Bounded, Int -> FileLogMultiSwitch
FileLogMultiSwitch -> Int
FileLogMultiSwitch -> [FileLogMultiSwitch]
FileLogMultiSwitch -> FileLogMultiSwitch
FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
FileLogMultiSwitch
-> FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
(FileLogMultiSwitch -> FileLogMultiSwitch)
-> (FileLogMultiSwitch -> FileLogMultiSwitch)
-> (Int -> FileLogMultiSwitch)
-> (FileLogMultiSwitch -> Int)
-> (FileLogMultiSwitch -> [FileLogMultiSwitch])
-> (FileLogMultiSwitch
    -> FileLogMultiSwitch -> [FileLogMultiSwitch])
-> (FileLogMultiSwitch
    -> FileLogMultiSwitch -> [FileLogMultiSwitch])
-> (FileLogMultiSwitch
    -> FileLogMultiSwitch
    -> FileLogMultiSwitch
    -> [FileLogMultiSwitch])
-> Enum FileLogMultiSwitch
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 :: FileLogMultiSwitch -> FileLogMultiSwitch
succ :: FileLogMultiSwitch -> FileLogMultiSwitch
$cpred :: FileLogMultiSwitch -> FileLogMultiSwitch
pred :: FileLogMultiSwitch -> FileLogMultiSwitch
$ctoEnum :: Int -> FileLogMultiSwitch
toEnum :: Int -> FileLogMultiSwitch
$cfromEnum :: FileLogMultiSwitch -> Int
fromEnum :: FileLogMultiSwitch -> Int
$cenumFrom :: FileLogMultiSwitch -> [FileLogMultiSwitch]
enumFrom :: FileLogMultiSwitch -> [FileLogMultiSwitch]
$cenumFromThen :: FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
enumFromThen :: FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
$cenumFromTo :: FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
enumFromTo :: FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
$cenumFromThenTo :: FileLogMultiSwitch
-> FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
enumFromThenTo :: FileLogMultiSwitch
-> FileLogMultiSwitch -> FileLogMultiSwitch -> [FileLogMultiSwitch]
Enum)
  deriving ((forall ann. FileLogMultiSwitch -> Doc ann)
-> (forall ann. [FileLogMultiSwitch] -> Doc ann)
-> Pretty FileLogMultiSwitch
forall ann. [FileLogMultiSwitch] -> Doc ann
forall ann. FileLogMultiSwitch -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
$cpretty :: forall ann. FileLogMultiSwitch -> Doc ann
pretty :: forall ann. FileLogMultiSwitch -> Doc ann
$cprettyList :: forall ann. [FileLogMultiSwitch] -> Doc ann
prettyList :: forall ann. [FileLogMultiSwitch] -> Doc ann
Pretty) via PrettySwitch

instance Default FileLogMultiSwitch where
  def :: FileLogMultiSwitch
def = Bool -> FileLogMultiSwitch
MkFileLogMultiSwitch Bool
False

instance DecodeTOML FileLogMultiSwitch where
  tomlDecoder :: Decoder FileLogMultiSwitch
tomlDecoder = Bool -> FileLogMultiSwitch
MkFileLogMultiSwitch (Bool -> FileLogMultiSwitch)
-> Decoder Bool -> Decoder FileLogMultiSwitch
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Decoder Text
forall a. DecodeTOML a => Decoder a
tomlDecoder Decoder Text -> (Text -> Decoder Bool) -> Decoder Bool
forall a b. Decoder a -> (a -> Decoder b) -> Decoder b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Decoder Bool
forall (m :: Type -> Type). MonadFail m => Text -> m Bool
parseSwitch)

instance
  (k ~ An_Iso, a ~ Bool, b ~ Bool) =>
  LabelOptic
    "unFileLogMultiSwitch"
    k
    FileLogMultiSwitch
    FileLogMultiSwitch
    a
    b
  where
  labelOptic :: Optic k NoIx FileLogMultiSwitch FileLogMultiSwitch a b
labelOptic = (FileLogMultiSwitch -> a)
-> (b -> FileLogMultiSwitch)
-> Iso FileLogMultiSwitch FileLogMultiSwitch a b
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(MkFileLogMultiSwitch Bool
b) -> a
Bool
b) b -> FileLogMultiSwitch
Bool -> FileLogMultiSwitch
MkFileLogMultiSwitch
  {-# INLINE labelOptic #-}

-- NOTE: [Args vs. Toml mandatory fields]
--
-- Some "aggregate types" (e.g. FileLogging, NotifyConfig) are optional
-- on the config itself i.e. they are surrounded by Maybe. This is opposed
-- to normal types (e.g. ConsoleLogging) that always exist.
--
-- We do this because it makes it easier to verify whether certain actions
-- should be "on" at all. For instance, if file-logging has not been set
-- (the user has not given us any 'path'), then not only do we not want to
-- log anything (fine, the field is Nothing), but we also do not want to
-- send any log messages to the queue, since that is just wasted work.
--
-- Similarly, if the user has not set any notify actions, then we do not
-- want to send any to its queue.
--
-- By surrounding the entire config in a maybe, we do not need to worry about
-- checking any implicit invariants ("only send notif to queue if some
-- action is set").
--
-- This generally means that the important fields (file-log path,
-- notify action), will be required on if the config exists.

-- | File logging's path is only optional for the Args and Toml. For merged,
-- it must be present if file logging is active.
type FileLogPathF :: ConfigPhase -> Type
type family FileLogPathF p where
  FileLogPathF ConfigPhaseArgs = Maybe (WithDisabled FilePathDefault)
  FileLogPathF ConfigPhaseToml = Maybe (WithDisabled FilePathDefault)
  FileLogPathF ConfigPhaseMerged = FilePathDefault

-- | Initial file log params, for usage before we create the final Env.
data FileLogInitP p = MkFileLogInitP
  { -- | Optional path to log file.
    forall (p :: ConfigPhase). FileLogInitP p -> FileLogPathF p
path :: FileLogPathF p,
    -- | Threshold for when we should warn about the log file size.
    forall (p :: ConfigPhase).
FileLogInitP p -> ConfigPhaseF p FileSizeMode
sizeMode :: ConfigPhaseF p FileSizeMode
  }

instance
  ( k ~ A_Lens,
    a ~ FileLogPathF p,
    b ~ FileLogPathF p
  ) =>
  LabelOptic "path" k (FileLogInitP p) (FileLogInitP p) a b
  where
  labelOptic :: Optic k NoIx (FileLogInitP p) (FileLogInitP p) a b
labelOptic =
    LensVL (FileLogInitP p) (FileLogInitP p) a b
-> Lens (FileLogInitP p) (FileLogInitP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLogInitP p) (FileLogInitP p) a b
 -> Lens (FileLogInitP p) (FileLogInitP p) a b)
-> LensVL (FileLogInitP p) (FileLogInitP p) a b
-> Lens (FileLogInitP p) (FileLogInitP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLogInitP FileLogPathF p
a1 ConfigPhaseF p FileSizeMode
a2) ->
        (b -> FileLogInitP p) -> f b -> f (FileLogInitP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogPathF p -> ConfigPhaseF p FileSizeMode -> FileLogInitP p
forall (p :: ConfigPhase).
FileLogPathF p -> ConfigPhaseF p FileSizeMode -> FileLogInitP p
MkFileLogInitP b
FileLogPathF p
b ConfigPhaseF p FileSizeMode
a2)
          (a -> f b
f a
FileLogPathF p
a1)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ ConfigPhaseF p FileSizeMode,
    b ~ ConfigPhaseF p FileSizeMode
  ) =>
  LabelOptic "sizeMode" k (FileLogInitP p) (FileLogInitP p) a b
  where
  labelOptic :: Optic k NoIx (FileLogInitP p) (FileLogInitP p) a b
labelOptic =
    LensVL (FileLogInitP p) (FileLogInitP p) a b
-> Lens (FileLogInitP p) (FileLogInitP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLogInitP p) (FileLogInitP p) a b
 -> Lens (FileLogInitP p) (FileLogInitP p) a b)
-> LensVL (FileLogInitP p) (FileLogInitP p) a b
-> Lens (FileLogInitP p) (FileLogInitP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLogInitP FileLogPathF p
a1 ConfigPhaseF p FileSizeMode
a2) ->
        (b -> FileLogInitP p) -> f b -> f (FileLogInitP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogPathF p -> ConfigPhaseF p FileSizeMode -> FileLogInitP p
forall (p :: ConfigPhase).
FileLogPathF p -> ConfigPhaseF p FileSizeMode -> FileLogInitP p
MkFileLogInitP FileLogPathF p
a1 b
ConfigPhaseF p FileSizeMode
b)
          (a -> f b
f a
ConfigPhaseF p FileSizeMode
a2)
  {-# INLINE labelOptic #-}

instance Semigroup FileLogInitToml where
  FileLogInitToml
l <> :: FileLogInitToml -> FileLogInitToml -> FileLogInitToml
<> FileLogInitToml
r =
    MkFileLogInitP
      { path :: FileLogPathF 'ConfigPhaseToml
path = FileLogInitToml
l FileLogInitToml
-> Optic'
     A_Lens NoIx FileLogInitToml (Maybe (WithDisabled FilePathDefault))
-> Maybe (WithDisabled FilePathDefault)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLogInitToml (Maybe (WithDisabled FilePathDefault))
#path Maybe (WithDisabled FilePathDefault)
-> Maybe (WithDisabled FilePathDefault)
-> Maybe (WithDisabled FilePathDefault)
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLogInitToml
r FileLogInitToml
-> Optic'
     A_Lens NoIx FileLogInitToml (Maybe (WithDisabled FilePathDefault))
-> Maybe (WithDisabled FilePathDefault)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLogInitToml (Maybe (WithDisabled FilePathDefault))
#path,
        sizeMode :: ConfigPhaseF 'ConfigPhaseToml FileSizeMode
sizeMode = FileLogInitToml
l FileLogInitToml
-> Optic' A_Lens NoIx FileLogInitToml (Maybe FileSizeMode)
-> Maybe FileSizeMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLogInitToml (Maybe FileSizeMode)
#sizeMode Maybe FileSizeMode -> Maybe FileSizeMode -> Maybe FileSizeMode
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLogInitToml
r FileLogInitToml
-> Optic' A_Lens NoIx FileLogInitToml (Maybe FileSizeMode)
-> Maybe FileSizeMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLogInitToml (Maybe FileSizeMode)
#sizeMode
      }

instance Monoid FileLogInitToml where
  mempty :: FileLogInitToml
mempty =
    MkFileLogInitP
      { path :: FileLogPathF 'ConfigPhaseToml
path = Maybe (WithDisabled FilePathDefault)
FileLogPathF 'ConfigPhaseToml
forall a. Maybe a
Nothing,
        sizeMode :: ConfigPhaseF 'ConfigPhaseToml FileSizeMode
sizeMode = Maybe FileSizeMode
ConfigPhaseF 'ConfigPhaseToml FileSizeMode
forall a. Maybe a
Nothing
      }

type FileLogInitArgs = FileLogInitP ConfigPhaseArgs

type FileLogInitToml = FileLogInitP ConfigPhaseToml

type FileLogInitMerged = FileLogInitP ConfigPhaseMerged

deriving stock instance Eq FileLogInitArgs

deriving stock instance Show FileLogInitArgs

deriving stock instance Eq FileLogInitToml

deriving stock instance Show FileLogInitToml

deriving stock instance Eq FileLogInitMerged

deriving stock instance Show FileLogInitMerged

-- Only Default instance is for Args, since others require the Path.
instance Default FileLogInitArgs where
  def :: FileLogInitArgs
def =
    MkFileLogInitP
      { path :: FileLogPathF 'ConfigPhaseArgs
path = Maybe (WithDisabled FilePathDefault)
FileLogPathF 'ConfigPhaseArgs
forall a. Maybe a
Nothing,
        sizeMode :: ConfigPhaseF 'ConfigPhaseArgs FileSizeMode
sizeMode = Maybe FileSizeMode
ConfigPhaseF 'ConfigPhaseArgs FileSizeMode
forall a. Maybe a
Nothing
      }

instance DecodeTOML FileLogInitToml where
  tomlDecoder :: Decoder FileLogInitToml
tomlDecoder =
    Maybe (WithDisabled FilePathDefault)
-> Maybe FileSizeMode -> FileLogInitToml
FileLogPathF 'ConfigPhaseToml
-> ConfigPhaseF 'ConfigPhaseToml FileSizeMode -> FileLogInitToml
forall (p :: ConfigPhase).
FileLogPathF p -> ConfigPhaseF p FileSizeMode -> FileLogInitP p
MkFileLogInitP
      (Maybe (WithDisabled FilePathDefault)
 -> Maybe FileSizeMode -> FileLogInitToml)
-> Decoder (Maybe (WithDisabled FilePathDefault))
-> Decoder (Maybe FileSizeMode -> FileLogInitToml)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder (Maybe (WithDisabled FilePathDefault))
decodeFileLogging
      Decoder (Maybe FileSizeMode -> FileLogInitToml)
-> Decoder (Maybe FileSizeMode) -> Decoder FileLogInitToml
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe FileSizeMode)
decodeFileLogSizeMode

decodeFileLogging :: Decoder (Maybe (WithDisabled FilePathDefault))
decodeFileLogging :: Decoder (Maybe (WithDisabled FilePathDefault))
decodeFileLogging = Decoder (WithDisabled FilePathDefault)
-> Text -> Decoder (Maybe (WithDisabled FilePathDefault))
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder (WithDisabled FilePathDefault)
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"path"

decodeFileLogMode :: Decoder (Maybe FileMode)
decodeFileLogMode :: Decoder (Maybe FileMode)
decodeFileLogMode = Decoder FileMode -> Text -> Decoder (Maybe FileMode)
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder FileMode
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"mode"

decodeFileLogSizeMode :: Decoder (Maybe FileSizeMode)
decodeFileLogSizeMode :: Decoder (Maybe FileSizeMode)
decodeFileLogSizeMode = Decoder FileSizeMode -> Text -> Decoder (Maybe FileSizeMode)
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder FileSizeMode
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"size-mode"

-- | Params after we have opened the file for logging.
data FileLogOpened = MkFileLogOpened
  { -- | File handle.
    FileLogOpened -> LockedHandleW
handle :: ~LockedHandleW,
    -- | File path.
    FileLogOpened -> OsPath
path :: OsPath,
    -- | File log queue.
    FileLogOpened -> TBQueue FileLog
queue :: ~(TBQueue FileLog)
  }

instance
  ( k ~ A_Lens,
    a ~ LockedHandleW,
    b ~ LockedHandleW
  ) =>
  LabelOptic "handle" k FileLogOpened FileLogOpened a b
  where
  labelOptic :: Optic k NoIx FileLogOpened FileLogOpened a b
labelOptic =
    LensVL FileLogOpened FileLogOpened a b
-> Lens FileLogOpened FileLogOpened a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL FileLogOpened FileLogOpened a b
 -> Lens FileLogOpened FileLogOpened a b)
-> LensVL FileLogOpened FileLogOpened a b
-> Lens FileLogOpened FileLogOpened a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLogOpened LockedHandleW
a1 OsPath
a2 TBQueue FileLog
a3) ->
        (LockedHandleW -> FileLogOpened)
-> f LockedHandleW -> f FileLogOpened
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\LockedHandleW
b -> LockedHandleW -> OsPath -> TBQueue FileLog -> FileLogOpened
MkFileLogOpened LockedHandleW
b OsPath
a2 TBQueue FileLog
a3)
          (a -> f b
f a
LockedHandleW
a1)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ OsPath,
    b ~ OsPath
  ) =>
  LabelOptic "path" k FileLogOpened FileLogOpened a b
  where
  labelOptic :: Optic k NoIx FileLogOpened FileLogOpened a b
labelOptic =
    LensVL FileLogOpened FileLogOpened a b
-> Lens FileLogOpened FileLogOpened a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL FileLogOpened FileLogOpened a b
 -> Lens FileLogOpened FileLogOpened a b)
-> LensVL FileLogOpened FileLogOpened a b
-> Lens FileLogOpened FileLogOpened a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLogOpened LockedHandleW
a1 OsPath
a2 TBQueue FileLog
a3) ->
        (OsPath -> FileLogOpened) -> f OsPath -> f FileLogOpened
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\OsPath
b -> LockedHandleW -> OsPath -> TBQueue FileLog -> FileLogOpened
MkFileLogOpened LockedHandleW
a1 OsPath
b TBQueue FileLog
a3)
          (a -> f b
f a
OsPath
a2)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ TBQueue FileLog,
    b ~ TBQueue FileLog
  ) =>
  LabelOptic "queue" k FileLogOpened FileLogOpened a b
  where
  labelOptic :: Optic k NoIx FileLogOpened FileLogOpened a b
labelOptic =
    LensVL FileLogOpened FileLogOpened a b
-> Lens FileLogOpened FileLogOpened a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL FileLogOpened FileLogOpened a b
 -> Lens FileLogOpened FileLogOpened a b)
-> LensVL FileLogOpened FileLogOpened a b
-> Lens FileLogOpened FileLogOpened a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLogOpened LockedHandleW
a1 OsPath
a2 TBQueue FileLog
a3) ->
        (TBQueue FileLog -> FileLogOpened)
-> f (TBQueue FileLog) -> f FileLogOpened
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\TBQueue FileLog
b -> LockedHandleW -> OsPath -> TBQueue FileLog -> FileLogOpened
MkFileLogOpened LockedHandleW
a1 OsPath
a2 TBQueue FileLog
b)
          (a -> f b
f a
TBQueue FileLog
a3)
  {-# INLINE labelOptic #-}

type FileLogFileF :: ConfigPhase -> Type
type family FileLogFileF p where
  FileLogFileF ConfigPhaseArgs = FileLogInitP ConfigPhaseArgs
  FileLogFileF ConfigPhaseToml = FileLogInitP ConfigPhaseToml
  FileLogFileF ConfigPhaseMerged = FileLogInitP ConfigPhaseMerged
  FileLogFileF ConfigPhaseEnv = FileLogOpened

type FileLogMultiF :: ConfigPhase -> Type
type family FileLogMultiF p where
  FileLogMultiF ConfigPhaseArgs = Maybe FileLogMultiSwitch
  FileLogMultiF ConfigPhaseToml = Maybe FileLogMultiSwitch
  FileLogMultiF ConfigPhaseMerged = FileLogMultiSwitch
  FileLogMultiF ConfigPhaseEnv = Maybe (TVar Word16)

-- | Holds file logging config.
type FileLoggingP :: ConfigPhase -> Type
data FileLoggingP p = MkFileLoggingP
  { -- | File-related params.
    forall (p :: ConfigPhase). FileLoggingP p -> FileLogFileF p
file :: FileLogFileF p,
    -- | The max number of command characters to display in the file logs.
    forall (p :: ConfigPhase).
FileLoggingP p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
commandNameTrunc :: ConfigPhaseDisabledMaybeF p (Truncation TruncCommandName),
    -- | If active, deletes the log file upon success.
    forall (p :: ConfigPhase).
FileLoggingP p -> SwitchF p DeleteOnSuccessSwitch
deleteOnSuccess :: SwitchF p DeleteOnSuccessSwitch,
    -- | Determines to what extent we should remove control characters
    -- from file logs.
    forall (p :: ConfigPhase). FileLoggingP p -> LineTruncF p
lineTrunc :: LineTruncF p,
    -- | Mode to use with the file log.
    forall (p :: ConfigPhase).
FileLoggingP p -> ConfigPhaseF p FileMode
mode :: ConfigPhaseF p FileMode,
    -- | Switch for multi logs. At the env stage, this is a counter for the
    -- file name index.
    forall (p :: ConfigPhase). FileLoggingP p -> FileLogMultiF p
multi :: FileLogMultiF p,
    -- | Strip control
    forall (p :: ConfigPhase).
FileLoggingP p -> ConfigPhaseF p FileLogStripControl
stripControl :: ConfigPhaseF p FileLogStripControl
  }

instance
  ( k ~ A_Lens,
    a ~ FileLogFileF p,
    b ~ FileLogFileF p
  ) =>
  LabelOptic "file" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP b
FileLogFileF p
b ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7)
          (a -> f b
f a
FileLogFileF p
a1)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ ConfigPhaseDisabledMaybeF p (Truncation TruncCommandName),
    b ~ ConfigPhaseDisabledMaybeF p (Truncation TruncCommandName)
  ) =>
  LabelOptic "commandNameTrunc" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP FileLogFileF p
a1 b
ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
b SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7)
          (a -> f b
f a
ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ SwitchF p DeleteOnSuccessSwitch,
    b ~ SwitchF p DeleteOnSuccessSwitch
  ) =>
  LabelOptic "deleteOnSuccess" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 b
SwitchF p DeleteOnSuccessSwitch
b LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7)
          (a -> f b
f a
SwitchF p DeleteOnSuccessSwitch
a3)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ LineTruncF p,
    b ~ LineTruncF p
  ) =>
  LabelOptic "lineTrunc" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 b
LineTruncF p
b ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7)
          (a -> f b
f a
LineTruncF p
a4)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ ConfigPhaseF p FileMode,
    b ~ ConfigPhaseF p FileMode
  ) =>
  LabelOptic "mode" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 b
ConfigPhaseF p FileMode
b FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7)
          (a -> f b
f a
ConfigPhaseF p FileMode
a5)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ FileLogMultiF p,
    b ~ FileLogMultiF p
  ) =>
  LabelOptic "multi" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 b
FileLogMultiF p
b ConfigPhaseF p FileLogStripControl
a7)
          (a -> f b
f a
FileLogMultiF p
a6)
  {-# INLINE labelOptic #-}

instance
  ( k ~ A_Lens,
    a ~ ConfigPhaseF p FileLogStripControl,
    b ~ ConfigPhaseF p FileLogStripControl
  ) =>
  LabelOptic "stripControl" k (FileLoggingP p) (FileLoggingP p) a b
  where
  labelOptic :: Optic k NoIx (FileLoggingP p) (FileLoggingP p) a b
labelOptic =
    LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall s t a b. LensVL s t a b -> Lens s t a b
lensVL
      (LensVL (FileLoggingP p) (FileLoggingP p) a b
 -> Lens (FileLoggingP p) (FileLoggingP p) a b)
-> LensVL (FileLoggingP p) (FileLoggingP p) a b
-> Lens (FileLoggingP p) (FileLoggingP p) a b
forall a b. (a -> b) -> a -> b
$ \a -> f b
f (MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 ConfigPhaseF p FileLogStripControl
a7) ->
        (b -> FileLoggingP p) -> f b -> f (FileLoggingP p)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
          (\b
b -> FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP FileLogFileF p
a1 ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
a2 SwitchF p DeleteOnSuccessSwitch
a3 LineTruncF p
a4 ConfigPhaseF p FileMode
a5 FileLogMultiF p
a6 b
ConfigPhaseF p FileLogStripControl
b)
          (a -> f b
f a
ConfigPhaseF p FileLogStripControl
a7)
  {-# INLINE labelOptic #-}

instance Semigroup FileLoggingToml where
  FileLoggingToml
l <> :: FileLoggingToml -> FileLoggingToml -> FileLoggingToml
<> FileLoggingToml
r =
    MkFileLoggingP
      { file :: FileLogFileF 'ConfigPhaseToml
file = FileLoggingToml
l FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
-> FileLogInitToml
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
#file FileLogInitToml -> FileLogInitToml -> FileLogInitToml
forall a. Semigroup a => a -> a -> a
<> FileLoggingToml
r FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
-> FileLogInitToml
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
#file,
        commandNameTrunc :: ConfigPhaseDisabledMaybeF
  'ConfigPhaseToml (Truncation 'TruncCommandName)
commandNameTrunc = FileLoggingToml
l FileLoggingToml
-> Optic'
     A_Lens
     NoIx
     FileLoggingToml
     (Maybe (WithDisabled (Truncation 'TruncCommandName)))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  FileLoggingToml
  (Maybe (WithDisabled (Truncation 'TruncCommandName)))
#commandNameTrunc Maybe (WithDisabled (Truncation 'TruncCommandName))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLoggingToml
r FileLoggingToml
-> Optic'
     A_Lens
     NoIx
     FileLoggingToml
     (Maybe (WithDisabled (Truncation 'TruncCommandName)))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  FileLoggingToml
  (Maybe (WithDisabled (Truncation 'TruncCommandName)))
#commandNameTrunc,
        deleteOnSuccess :: SwitchF 'ConfigPhaseToml DeleteOnSuccessSwitch
deleteOnSuccess = FileLoggingToml
l FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe DeleteOnSuccessSwitch)
-> Maybe DeleteOnSuccessSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe DeleteOnSuccessSwitch)
#deleteOnSuccess Maybe DeleteOnSuccessSwitch
-> Maybe DeleteOnSuccessSwitch -> Maybe DeleteOnSuccessSwitch
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLoggingToml
r FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe DeleteOnSuccessSwitch)
-> Maybe DeleteOnSuccessSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe DeleteOnSuccessSwitch)
#deleteOnSuccess,
        lineTrunc :: LineTruncF 'ConfigPhaseToml
lineTrunc = FileLoggingToml
l FileLoggingToml
-> Optic'
     A_Lens NoIx FileLoggingToml (Maybe (WithDisabled LineTruncation))
-> Maybe (WithDisabled LineTruncation)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLoggingToml (Maybe (WithDisabled LineTruncation))
#lineTrunc Maybe (WithDisabled LineTruncation)
-> Maybe (WithDisabled LineTruncation)
-> Maybe (WithDisabled LineTruncation)
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLoggingToml
r FileLoggingToml
-> Optic'
     A_Lens NoIx FileLoggingToml (Maybe (WithDisabled LineTruncation))
-> Maybe (WithDisabled LineTruncation)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLoggingToml (Maybe (WithDisabled LineTruncation))
#lineTrunc,
        mode :: ConfigPhaseF 'ConfigPhaseToml FileMode
mode = FileLoggingToml
l FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileMode)
-> Maybe FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileMode)
#mode Maybe FileMode -> Maybe FileMode -> Maybe FileMode
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLoggingToml
r FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileMode)
-> Maybe FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileMode)
#mode,
        multi :: FileLogMultiF 'ConfigPhaseToml
multi = FileLoggingToml
l FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogMultiSwitch)
-> Maybe FileLogMultiSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogMultiSwitch)
#multi Maybe FileLogMultiSwitch
-> Maybe FileLogMultiSwitch -> Maybe FileLogMultiSwitch
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLoggingToml
r FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogMultiSwitch)
-> Maybe FileLogMultiSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogMultiSwitch)
#multi,
        stripControl :: ConfigPhaseF 'ConfigPhaseToml FileLogStripControl
stripControl = FileLoggingToml
l FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogStripControl)
-> Maybe FileLogStripControl
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogStripControl)
#stripControl Maybe FileLogStripControl
-> Maybe FileLogStripControl -> Maybe FileLogStripControl
forall a. Maybe a -> Maybe a -> Maybe a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> FileLoggingToml
r FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogStripControl)
-> Maybe FileLogStripControl
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogStripControl)
#stripControl
      }

instance Monoid FileLoggingToml where
  mempty :: FileLoggingToml
mempty =
    MkFileLoggingP
      { file :: FileLogFileF 'ConfigPhaseToml
file = FileLogFileF 'ConfigPhaseToml
FileLogInitToml
forall a. Monoid a => a
mempty,
        commandNameTrunc :: ConfigPhaseDisabledMaybeF
  'ConfigPhaseToml (Truncation 'TruncCommandName)
commandNameTrunc = Maybe (WithDisabled (Truncation 'TruncCommandName))
ConfigPhaseDisabledMaybeF
  'ConfigPhaseToml (Truncation 'TruncCommandName)
forall a. Maybe a
Nothing,
        deleteOnSuccess :: SwitchF 'ConfigPhaseToml DeleteOnSuccessSwitch
deleteOnSuccess = Maybe DeleteOnSuccessSwitch
SwitchF 'ConfigPhaseToml DeleteOnSuccessSwitch
forall a. Maybe a
Nothing,
        lineTrunc :: LineTruncF 'ConfigPhaseToml
lineTrunc = Maybe (WithDisabled LineTruncation)
LineTruncF 'ConfigPhaseToml
forall a. Maybe a
Nothing,
        mode :: ConfigPhaseF 'ConfigPhaseToml FileMode
mode = Maybe FileMode
ConfigPhaseF 'ConfigPhaseToml FileMode
forall a. Maybe a
Nothing,
        multi :: FileLogMultiF 'ConfigPhaseToml
multi = Maybe FileLogMultiSwitch
FileLogMultiF 'ConfigPhaseToml
forall a. Maybe a
Nothing,
        stripControl :: ConfigPhaseF 'ConfigPhaseToml FileLogStripControl
stripControl = Maybe FileLogStripControl
ConfigPhaseF 'ConfigPhaseToml FileLogStripControl
forall a. Maybe a
Nothing
      }

instance Pretty FileLoggingMerged where
  pretty :: forall ann. FileLoggingMerged -> Doc ann
pretty FileLoggingMerged
c =
    [Doc ann] -> Doc ann
forall ann. [Doc ann] -> Doc ann
vcat
      [ Doc ann
"command-name-trunc: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Maybe (Truncation 'TruncCommandName) -> Doc ann
forall a ann. Pretty a => Maybe a -> Doc ann
prettyMaybe (FileLoggingMerged
c FileLoggingMerged
-> Optic'
     A_Lens
     NoIx
     FileLoggingMerged
     (Maybe (Truncation 'TruncCommandName))
-> Maybe (Truncation 'TruncCommandName)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  FileLoggingMerged
  (Maybe (Truncation 'TruncCommandName))
#commandNameTrunc),
        Doc ann
"delete-on-success: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> DeleteOnSuccessSwitch -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. DeleteOnSuccessSwitch -> Doc ann
pretty (FileLoggingMerged
c FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged DeleteOnSuccessSwitch
#deleteOnSuccess),
        Doc ann
"line-trunc: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> Maybe (Truncation 'TruncLine) -> Doc ann
forall a ann. Pretty a => Maybe a -> Doc ann
prettyMaybe (FileLoggingMerged
c FileLoggingMerged
-> Optic'
     A_Lens NoIx FileLoggingMerged (Maybe (Truncation 'TruncLine))
-> Maybe (Truncation 'TruncLine)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLoggingMerged (Maybe (Truncation 'TruncLine))
#lineTrunc),
        Doc ann
"mode: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FileMode -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FileMode -> Doc ann
pretty (FileLoggingMerged
c FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileMode -> FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileMode
#mode),
        Doc ann
"multi: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FileLogMultiSwitch -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FileLogMultiSwitch -> Doc ann
pretty (FileLoggingMerged
c FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileLogMultiSwitch
-> FileLogMultiSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileLogMultiSwitch
#multi),
        Doc ann
"path: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FilePathDefault -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FilePathDefault -> Doc ann
pretty (FileLoggingMerged
c FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FilePathDefault
-> FilePathDefault
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
#file Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
-> Optic
     A_Lens
     NoIx
     FileLogInitMerged
     FileLogInitMerged
     FilePathDefault
     FilePathDefault
-> Optic' A_Lens NoIx FileLoggingMerged FilePathDefault
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitMerged
  FileLogInitMerged
  FilePathDefault
  FilePathDefault
#path),
        Doc ann
"size-mode: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FileSizeMode -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FileSizeMode -> Doc ann
pretty (FileLoggingMerged
c FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileSizeMode
-> FileSizeMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
#file Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
-> Optic
     A_Lens
     NoIx
     FileLogInitMerged
     FileLogInitMerged
     FileSizeMode
     FileSizeMode
-> Optic' A_Lens NoIx FileLoggingMerged FileSizeMode
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitMerged
  FileLogInitMerged
  FileSizeMode
  FileSizeMode
#sizeMode),
        Doc ann
"strip-control: " Doc ann -> Doc ann -> Doc ann
forall a. Semigroup a => a -> a -> a
<> FileLogStripControl -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. FileLogStripControl -> Doc ann
pretty (FileLoggingMerged
c FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileLogStripControl
-> FileLogStripControl
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileLogStripControl
#stripControl)
      ]

type FileLoggingArgs = FileLoggingP ConfigPhaseArgs

type FileLoggingToml = FileLoggingP ConfigPhaseToml

type FileLoggingMerged = FileLoggingP ConfigPhaseMerged

type FileLoggingEnv = FileLoggingP ConfigPhaseEnv

deriving stock instance Eq (FileLoggingP ConfigPhaseArgs)

deriving stock instance Show (FileLoggingP ConfigPhaseArgs)

deriving stock instance Eq (FileLoggingP ConfigPhaseToml)

deriving stock instance Show (FileLoggingP ConfigPhaseToml)

deriving stock instance Eq (FileLoggingP ConfigPhaseMerged)

deriving stock instance Show (FileLoggingP ConfigPhaseMerged)

instance Default FileLoggingArgs where
  def :: FileLoggingP 'ConfigPhaseArgs
def =
    MkFileLoggingP
      { file :: FileLogFileF 'ConfigPhaseArgs
file = FileLogFileF 'ConfigPhaseArgs
FileLogInitArgs
forall a. Default a => a
def,
        commandNameTrunc :: ConfigPhaseDisabledMaybeF
  'ConfigPhaseArgs (Truncation 'TruncCommandName)
commandNameTrunc = Maybe (WithDisabled (Truncation 'TruncCommandName))
ConfigPhaseDisabledMaybeF
  'ConfigPhaseArgs (Truncation 'TruncCommandName)
forall a. Maybe a
Nothing,
        deleteOnSuccess :: SwitchF 'ConfigPhaseArgs DeleteOnSuccessSwitch
deleteOnSuccess = Maybe DeleteOnSuccessSwitch
SwitchF 'ConfigPhaseArgs DeleteOnSuccessSwitch
forall a. Maybe a
Nothing,
        lineTrunc :: LineTruncF 'ConfigPhaseArgs
lineTrunc = Maybe (WithDisabled LineTruncation)
LineTruncF 'ConfigPhaseArgs
forall a. Maybe a
Nothing,
        mode :: ConfigPhaseF 'ConfigPhaseArgs FileMode
mode = Maybe FileMode
ConfigPhaseF 'ConfigPhaseArgs FileMode
forall a. Maybe a
Nothing,
        multi :: FileLogMultiF 'ConfigPhaseArgs
multi = Maybe FileLogMultiSwitch
FileLogMultiF 'ConfigPhaseArgs
forall a. Maybe a
Nothing,
        stripControl :: ConfigPhaseF 'ConfigPhaseArgs FileLogStripControl
stripControl = Maybe FileLogStripControl
ConfigPhaseF 'ConfigPhaseArgs FileLogStripControl
forall a. Maybe a
Nothing
      }

-- | Merges args and toml configs.
mergeFileLogging ::
  ( HasCallStack,
    MonadCatch m,
    MonadIORef m,
    MonadTerminal m
  ) =>
  NESeq CommandP1 ->
  IORef DetectResult ->
  FileLoggingArgs ->
  Maybe FileLoggingToml ->
  m (Maybe FileLoggingMerged)
mergeFileLogging :: forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadIORef m, MonadTerminal m) =>
NESeq CommandP1
-> IORef DetectResult
-> FileLoggingP 'ConfigPhaseArgs
-> Maybe FileLoggingToml
-> m (Maybe FileLoggingMerged)
mergeFileLogging NESeq CommandP1
cmds IORef DetectResult
detectRef FileLoggingP 'ConfigPhaseArgs
args Maybe FileLoggingToml
mToml = Maybe FilePathDefault
-> (FilePathDefault -> m FileLoggingMerged)
-> m (Maybe FileLoggingMerged)
forall (t :: Type -> Type) (f :: Type -> Type) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for Maybe FilePathDefault
mPath ((FilePathDefault -> m FileLoggingMerged)
 -> m (Maybe FileLoggingMerged))
-> (FilePathDefault -> m FileLoggingMerged)
-> m (Maybe FileLoggingMerged)
forall a b. (a -> b) -> a -> b
$ \FilePathDefault
path -> do
  let toml :: FileLoggingToml
toml = FileLoggingToml -> Maybe FileLoggingToml -> FileLoggingToml
forall a. a -> Maybe a -> a
fromMaybe FileLoggingToml
defaultToml Maybe FileLoggingToml
mToml

  Maybe (Truncation 'TruncLine)
lineTrunc <-
    Bool
-> IORef DetectResult
-> Maybe (WithDisabled LineTruncation)
-> Maybe (WithDisabled LineTruncation)
-> m (Maybe (Truncation 'TruncLine))
forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadIORef m, MonadTerminal m) =>
Bool
-> IORef DetectResult
-> Maybe (WithDisabled LineTruncation)
-> Maybe (WithDisabled LineTruncation)
-> m (Maybe (Truncation 'TruncLine))
mergeLineTrunc Bool
False IORef DetectResult
detectRef (FileLoggingP 'ConfigPhaseArgs
args FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe (WithDisabled LineTruncation))
-> Maybe (WithDisabled LineTruncation)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (Maybe (WithDisabled LineTruncation))
#lineTrunc) (FileLoggingToml
toml FileLoggingToml
-> Optic'
     A_Lens NoIx FileLoggingToml (Maybe (WithDisabled LineTruncation))
-> Maybe (WithDisabled LineTruncation)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLoggingToml (Maybe (WithDisabled LineTruncation))
#lineTrunc)

  -- Only enable multi logging if the flag is active and commands > 1.
  let multi :: FileLogMultiSwitch
multi =
        if NESeq CommandP1 -> Int
forall a. NESeq a -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length NESeq CommandP1
cmds Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2
          then Bool -> FileLogMultiSwitch
MkFileLogMultiSwitch Bool
False
          else
            FileLoggingP 'ConfigPhaseArgs
args
              FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe FileLogMultiSwitch)
-> Maybe FileLogMultiSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (Maybe FileLogMultiSwitch)
#multi
              Maybe FileLogMultiSwitch
-> Maybe FileLogMultiSwitch -> FileLogMultiSwitch
forall a. Default a => Maybe a -> Maybe a -> a
<.> (FileLoggingToml
toml FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogMultiSwitch)
-> Maybe FileLogMultiSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogMultiSwitch)
#multi)
  pure
    $ MkFileLoggingP
      { file :: FileLogFileF 'ConfigPhaseMerged
file =
          MkFileLogInitP
            { FilePathDefault
FileLogPathF 'ConfigPhaseMerged
path :: FileLogPathF 'ConfigPhaseMerged
path :: FilePathDefault
path,
              sizeMode :: ConfigPhaseF 'ConfigPhaseMerged FileSizeMode
sizeMode =
                (FileLoggingP 'ConfigPhaseArgs
args FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
-> Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (FileLoggingP 'ConfigPhaseArgs)
  FileLogInitArgs
  FileLogInitArgs
#file Optic
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (FileLoggingP 'ConfigPhaseArgs)
  FileLogInitArgs
  FileLogInitArgs
-> Optic
     A_Lens
     NoIx
     FileLogInitArgs
     FileLogInitArgs
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitArgs
  FileLogInitArgs
  (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
  (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
#sizeMode) Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode)
-> Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode)
-> ConfigPhaseF 'ConfigPhaseMerged FileSizeMode
forall a. Default a => Maybe a -> Maybe a -> a
<.> (FileLoggingToml
toml FileLoggingToml
-> Optic'
     A_Lens
     NoIx
     FileLoggingToml
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
-> Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
#file Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
-> Optic
     A_Lens
     NoIx
     FileLogInitToml
     FileLogInitToml
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
-> Optic'
     A_Lens
     NoIx
     FileLoggingToml
     (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitToml
  FileLogInitToml
  (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
  (Maybe (ConfigPhaseF 'ConfigPhaseMerged FileSizeMode))
#sizeMode)
            },
        commandNameTrunc :: ConfigPhaseDisabledMaybeF
  'ConfigPhaseMerged (Truncation 'TruncCommandName)
commandNameTrunc =
          (FileLoggingP 'ConfigPhaseArgs
args FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe (WithDisabled (Truncation 'TruncCommandName)))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (Maybe (WithDisabled (Truncation 'TruncCommandName)))
#commandNameTrunc) Maybe (WithDisabled (Truncation 'TruncCommandName))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
-> Maybe (Truncation 'TruncCommandName)
forall a.
Maybe (WithDisabled a) -> Maybe (WithDisabled a) -> Maybe a
<|?|> (FileLoggingToml
toml FileLoggingToml
-> Optic'
     A_Lens
     NoIx
     FileLoggingToml
     (Maybe (WithDisabled (Truncation 'TruncCommandName)))
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  FileLoggingToml
  (Maybe (WithDisabled (Truncation 'TruncCommandName)))
#commandNameTrunc),
        deleteOnSuccess :: SwitchF 'ConfigPhaseMerged DeleteOnSuccessSwitch
deleteOnSuccess =
          FileLoggingP 'ConfigPhaseArgs
args
            FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe DeleteOnSuccessSwitch)
-> Maybe DeleteOnSuccessSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (Maybe DeleteOnSuccessSwitch)
#deleteOnSuccess
            Maybe DeleteOnSuccessSwitch
-> Maybe DeleteOnSuccessSwitch -> DeleteOnSuccessSwitch
forall a. Default a => Maybe a -> Maybe a -> a
<.> (FileLoggingToml
toml FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe DeleteOnSuccessSwitch)
-> Maybe DeleteOnSuccessSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe DeleteOnSuccessSwitch)
#deleteOnSuccess),
        Maybe (Truncation 'TruncLine)
LineTruncF 'ConfigPhaseMerged
lineTrunc :: LineTruncF 'ConfigPhaseMerged
lineTrunc :: Maybe (Truncation 'TruncLine)
lineTrunc,
        mode :: ConfigPhaseF 'ConfigPhaseMerged FileMode
mode = (FileLoggingP 'ConfigPhaseArgs
args FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens NoIx (FileLoggingP 'ConfigPhaseArgs) (Maybe FileMode)
-> Maybe FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx (FileLoggingP 'ConfigPhaseArgs) (Maybe FileMode)
#mode) Maybe FileMode -> Maybe FileMode -> FileMode
forall a. Default a => Maybe a -> Maybe a -> a
<.> (FileLoggingToml
toml FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileMode)
-> Maybe FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileMode)
#mode),
        FileLogMultiF 'ConfigPhaseMerged
FileLogMultiSwitch
multi :: FileLogMultiF 'ConfigPhaseMerged
multi :: FileLogMultiSwitch
multi,
        stripControl :: ConfigPhaseF 'ConfigPhaseMerged FileLogStripControl
stripControl =
          (FileLoggingP 'ConfigPhaseArgs
args FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe FileLogStripControl)
-> Maybe FileLogStripControl
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (Maybe FileLogStripControl)
#stripControl) Maybe FileLogStripControl
-> Maybe FileLogStripControl -> FileLogStripControl
forall a. Default a => Maybe a -> Maybe a -> a
<.> (FileLoggingToml
toml FileLoggingToml
-> Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogStripControl)
-> Maybe FileLogStripControl
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingToml (Maybe FileLogStripControl)
#stripControl)
      }
  where
    -- NOTE: [Config two-part pattern matching]
    --
    -- Why do we pattern match here and in the main body of mergeFileLogging,
    -- rather than just once? If we did all of it in the body we'd have logic
    -- like:
    --
    --     if Disabled and No Toml
    --       Nothing
    --     else if No args and No Toml
    --       Nothing
    --     else if Args and No Toml
    --       Just fileLogging ...
    --     else if No Args and Toml
    --       Just fileLogging ...
    --     else Args and Toml
    --       Just fileLogging ..
    --
    -- That is, we'd repeat the "Just fileLogging" step several types, and
    -- since it is already quite wordy, readability suffers. It is easier to
    -- reduce the pattern matching down to a "go no-go" switch first, then
    -- make the fileLogging based on that.
    mPath :: Maybe FilePathDefault
    mPath :: Maybe FilePathDefault
mPath = FileLoggingP 'ConfigPhaseArgs
args FileLoggingP 'ConfigPhaseArgs
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe (WithDisabled FilePathDefault))
-> Maybe (WithDisabled FilePathDefault)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (FileLoggingP 'ConfigPhaseArgs)
  FileLogInitArgs
  FileLogInitArgs
#file Optic
  A_Lens
  NoIx
  (FileLoggingP 'ConfigPhaseArgs)
  (FileLoggingP 'ConfigPhaseArgs)
  FileLogInitArgs
  FileLogInitArgs
-> Optic
     A_Lens
     NoIx
     FileLogInitArgs
     FileLogInitArgs
     (Maybe (WithDisabled FilePathDefault))
     (Maybe (WithDisabled FilePathDefault))
-> Optic'
     A_Lens
     NoIx
     (FileLoggingP 'ConfigPhaseArgs)
     (Maybe (WithDisabled FilePathDefault))
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitArgs
  FileLogInitArgs
  (Maybe (WithDisabled FilePathDefault))
  (Maybe (WithDisabled FilePathDefault))
#path Maybe (WithDisabled FilePathDefault)
-> Maybe (WithDisabled FilePathDefault) -> Maybe FilePathDefault
forall a.
Maybe (WithDisabled a) -> Maybe (WithDisabled a) -> Maybe a
<|?|> (Maybe FileLoggingToml
mToml Maybe FileLoggingToml
-> Optic'
     An_AffineTraversal
     NoIx
     (Maybe FileLoggingToml)
     (WithDisabled FilePathDefault)
-> Maybe (WithDisabled FilePathDefault)
forall k s (is :: IxList) a.
Is k An_AffineFold =>
s -> Optic' k is s a -> Maybe a
^? Optic
  A_Lens
  NoIx
  FileLoggingToml
  FileLoggingToml
  (Maybe (WithDisabled FilePathDefault))
  (Maybe (WithDisabled FilePathDefault))
-> Optic'
     An_AffineTraversal
     NoIx
     (Maybe FileLoggingToml)
     (WithDisabled FilePathDefault)
forall k m l (ks :: IxList) u v a b.
(JoinKinds k A_Prism m, JoinKinds A_Prism l k) =>
Optic l ks u v (Maybe a) (Maybe b)
-> Optic m ks (Maybe u) (Maybe v) a b
Utils.surroundJust (Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
#file Optic' A_Lens NoIx FileLoggingToml FileLogInitToml
-> Optic'
     A_Lens NoIx FileLogInitToml (Maybe (WithDisabled FilePathDefault))
-> Optic
     A_Lens
     NoIx
     FileLoggingToml
     FileLoggingToml
     (Maybe (WithDisabled FilePathDefault))
     (Maybe (WithDisabled FilePathDefault))
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic'
  A_Lens NoIx FileLogInitToml (Maybe (WithDisabled FilePathDefault))
#path))
{-# INLINEABLE mergeFileLogging #-}

instance DecodeTOML FileLoggingToml where
  tomlDecoder :: Decoder FileLoggingToml
tomlDecoder =
    FileLogFileF 'ConfigPhaseToml
-> ConfigPhaseDisabledMaybeF
     'ConfigPhaseToml (Truncation 'TruncCommandName)
-> SwitchF 'ConfigPhaseToml DeleteOnSuccessSwitch
-> LineTruncF 'ConfigPhaseToml
-> ConfigPhaseF 'ConfigPhaseToml FileMode
-> FileLogMultiF 'ConfigPhaseToml
-> ConfigPhaseF 'ConfigPhaseToml FileLogStripControl
-> FileLoggingToml
FileLogInitToml
-> Maybe (WithDisabled (Truncation 'TruncCommandName))
-> Maybe DeleteOnSuccessSwitch
-> Maybe (WithDisabled LineTruncation)
-> Maybe FileMode
-> Maybe FileLogMultiSwitch
-> Maybe FileLogStripControl
-> FileLoggingToml
forall (p :: ConfigPhase).
FileLogFileF p
-> ConfigPhaseDisabledMaybeF p (Truncation 'TruncCommandName)
-> SwitchF p DeleteOnSuccessSwitch
-> LineTruncF p
-> ConfigPhaseF p FileMode
-> FileLogMultiF p
-> ConfigPhaseF p FileLogStripControl
-> FileLoggingP p
MkFileLoggingP
      (FileLogInitToml
 -> Maybe (WithDisabled (Truncation 'TruncCommandName))
 -> Maybe DeleteOnSuccessSwitch
 -> Maybe (WithDisabled LineTruncation)
 -> Maybe FileMode
 -> Maybe FileLogMultiSwitch
 -> Maybe FileLogStripControl
 -> FileLoggingToml)
-> Decoder FileLogInitToml
-> Decoder
     (Maybe (WithDisabled (Truncation 'TruncCommandName))
      -> Maybe DeleteOnSuccessSwitch
      -> Maybe (WithDisabled LineTruncation)
      -> Maybe FileMode
      -> Maybe FileLogMultiSwitch
      -> Maybe FileLogStripControl
      -> FileLoggingToml)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder FileLogInitToml
forall a. DecodeTOML a => Decoder a
tomlDecoder
      Decoder
  (Maybe (WithDisabled (Truncation 'TruncCommandName))
   -> Maybe DeleteOnSuccessSwitch
   -> Maybe (WithDisabled LineTruncation)
   -> Maybe FileMode
   -> Maybe FileLogMultiSwitch
   -> Maybe FileLogStripControl
   -> FileLoggingToml)
-> Decoder (Maybe (WithDisabled (Truncation 'TruncCommandName)))
-> Decoder
     (Maybe DeleteOnSuccessSwitch
      -> Maybe (WithDisabled LineTruncation)
      -> Maybe FileMode
      -> Maybe FileLogMultiSwitch
      -> Maybe FileLogStripControl
      -> FileLoggingToml)
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe (WithDisabled (Truncation 'TruncCommandName)))
decodeCommandNameTrunc
      Decoder
  (Maybe DeleteOnSuccessSwitch
   -> Maybe (WithDisabled LineTruncation)
   -> Maybe FileMode
   -> Maybe FileLogMultiSwitch
   -> Maybe FileLogStripControl
   -> FileLoggingToml)
-> Decoder (Maybe DeleteOnSuccessSwitch)
-> Decoder
     (Maybe (WithDisabled LineTruncation)
      -> Maybe FileMode
      -> Maybe FileLogMultiSwitch
      -> Maybe FileLogStripControl
      -> FileLoggingToml)
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe DeleteOnSuccessSwitch)
decodeFileDeleteOnSuccess
      Decoder
  (Maybe (WithDisabled LineTruncation)
   -> Maybe FileMode
   -> Maybe FileLogMultiSwitch
   -> Maybe FileLogStripControl
   -> FileLoggingToml)
-> Decoder (Maybe (WithDisabled LineTruncation))
-> Decoder
     (Maybe FileMode
      -> Maybe FileLogMultiSwitch
      -> Maybe FileLogStripControl
      -> FileLoggingToml)
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe (WithDisabled LineTruncation))
decodeLineTrunc
      Decoder
  (Maybe FileMode
   -> Maybe FileLogMultiSwitch
   -> Maybe FileLogStripControl
   -> FileLoggingToml)
-> Decoder (Maybe FileMode)
-> Decoder
     (Maybe FileLogMultiSwitch
      -> Maybe FileLogStripControl -> FileLoggingToml)
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe FileMode)
decodeFileLogMode
      Decoder
  (Maybe FileLogMultiSwitch
   -> Maybe FileLogStripControl -> FileLoggingToml)
-> Decoder (Maybe FileLogMultiSwitch)
-> Decoder (Maybe FileLogStripControl -> FileLoggingToml)
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder FileLogMultiSwitch
-> Text -> Decoder (Maybe FileLogMultiSwitch)
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder FileLogMultiSwitch
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"multi"
      Decoder (Maybe FileLogStripControl -> FileLoggingToml)
-> Decoder (Maybe FileLogStripControl) -> Decoder FileLoggingToml
forall a b. Decoder (a -> b) -> Decoder a -> Decoder b
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe FileLogStripControl)
decodeFileLogStripControl

decodeFileDeleteOnSuccess :: Decoder (Maybe DeleteOnSuccessSwitch)
decodeFileDeleteOnSuccess :: Decoder (Maybe DeleteOnSuccessSwitch)
decodeFileDeleteOnSuccess = Decoder DeleteOnSuccessSwitch
-> Text -> Decoder (Maybe DeleteOnSuccessSwitch)
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder DeleteOnSuccessSwitch
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"delete-on-success"

decodeFileLogStripControl :: Decoder (Maybe FileLogStripControl)
decodeFileLogStripControl :: Decoder (Maybe FileLogStripControl)
decodeFileLogStripControl = Decoder FileLogStripControl
-> Text -> Decoder (Maybe FileLogStripControl)
forall a. Decoder a -> Text -> Decoder (Maybe a)
getFieldOptWith Decoder FileLogStripControl
forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"strip-control"

type MLogging =
  Maybe
    ( Tuple5
        FileLoggingMerged
        LockedHandleW
        OsPath
        (TBQueue FileLog)
        (Maybe (TVar Word16))
    )

-- | Given merged FileLogging config, constructs a FileLoggingEnv and calls
-- the continuation.
withFileLoggingEnv ::
  forall m a.
  ( HasCallStack,
    MonadAtomic m,
    MonadFileWriter m,
    MonadHandleWriter m,
    MonadMask m,
    MonadPathReader m,
    MonadPathWriter m,
    MonadPosixFiles m,
    MonadTerminal m
  ) =>
  Maybe FileLoggingMerged ->
  (Maybe FileLoggingEnv -> m a) ->
  m a
withFileLoggingEnv :: forall (m :: Type -> Type) a.
(HasCallStack, MonadAtomic m, MonadFileWriter m,
 MonadHandleWriter m, MonadMask m, MonadPathReader m,
 MonadPathWriter m, MonadPosixFiles m, MonadTerminal m) =>
Maybe FileLoggingMerged -> (Maybe FileLoggingEnv -> m a) -> m a
withFileLoggingEnv Maybe FileLoggingMerged
mFileLogging Maybe FileLoggingEnv -> m a
onFileLoggingEnv = do
  let mkEnv :: MLogging -> Maybe FileLoggingEnv
      mkEnv :: MLogging -> Maybe FileLoggingEnv
mkEnv MLogging
Nothing = Maybe FileLoggingEnv
forall a. Maybe a
Nothing
      mkEnv (Just (FileLoggingMerged
fl, LockedHandleW
h, OsPath
p, TBQueue FileLog
q, Maybe (TVar Word16)
mMultiCounter)) =
        FileLoggingEnv -> Maybe FileLoggingEnv
forall a. a -> Maybe a
Just
          (FileLoggingEnv -> Maybe FileLoggingEnv)
-> FileLoggingEnv -> Maybe FileLoggingEnv
forall a b. (a -> b) -> a -> b
$ MkFileLoggingP
            { file :: FileLogFileF 'ConfigPhaseEnv
file =
                MkFileLogOpened
                  { handle :: LockedHandleW
handle = LockedHandleW
h,
                    path :: OsPath
path = OsPath
p,
                    queue :: TBQueue FileLog
queue = TBQueue FileLog
q
                  },
              commandNameTrunc :: ConfigPhaseDisabledMaybeF
  'ConfigPhaseEnv (Truncation 'TruncCommandName)
commandNameTrunc = FileLoggingMerged
fl FileLoggingMerged
-> Optic'
     A_Lens
     NoIx
     FileLoggingMerged
     (Maybe (Truncation 'TruncCommandName))
-> Maybe (Truncation 'TruncCommandName)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens
  NoIx
  FileLoggingMerged
  (Maybe (Truncation 'TruncCommandName))
#commandNameTrunc,
              lineTrunc :: LineTruncF 'ConfigPhaseEnv
lineTrunc = FileLoggingMerged
fl FileLoggingMerged
-> Optic'
     A_Lens NoIx FileLoggingMerged (Maybe (Truncation 'TruncLine))
-> Maybe (Truncation 'TruncLine)
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic'
  A_Lens NoIx FileLoggingMerged (Maybe (Truncation 'TruncLine))
#lineTrunc,
              deleteOnSuccess :: SwitchF 'ConfigPhaseEnv DeleteOnSuccessSwitch
deleteOnSuccess = FileLoggingMerged
fl FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged DeleteOnSuccessSwitch
-> DeleteOnSuccessSwitch
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged DeleteOnSuccessSwitch
#deleteOnSuccess,
              mode :: ConfigPhaseF 'ConfigPhaseEnv FileMode
mode = FileLoggingMerged
fl FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileMode -> FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileMode
#mode,
              multi :: FileLogMultiF 'ConfigPhaseEnv
multi = Maybe (TVar Word16)
FileLogMultiF 'ConfigPhaseEnv
mMultiCounter,
              stripControl :: ConfigPhaseF 'ConfigPhaseEnv FileLogStripControl
stripControl = FileLoggingMerged
fl FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileLogStripControl
-> FileLogStripControl
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileLogStripControl
#stripControl
            }

  Maybe FileLoggingMerged -> (MLogging -> m a) -> m a
forall (m :: Type -> Type) a.
(HasCallStack, MonadAtomic m, MonadFileWriter m,
 MonadHandleWriter m, MonadMask m, MonadPathReader m,
 MonadPathWriter m, MonadPosixFiles m, MonadTerminal m) =>
Maybe FileLoggingMerged -> (MLogging -> m a) -> m a
withMLogging Maybe FileLoggingMerged
mFileLogging (Maybe FileLoggingEnv -> m a
onFileLoggingEnv (Maybe FileLoggingEnv -> m a)
-> (MLogging -> Maybe FileLoggingEnv) -> MLogging -> m a
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
. MLogging -> Maybe FileLoggingEnv
mkEnv)
{-# INLINEABLE withFileLoggingEnv #-}

withMLogging ::
  forall m a.
  ( HasCallStack,
    MonadAtomic m,
    MonadFileWriter m,
    MonadHandleWriter m,
    MonadMask m,
    MonadPathReader m,
    MonadPathWriter m,
    MonadPosixFiles m,
    MonadTerminal m
  ) =>
  Maybe FileLoggingMerged ->
  (MLogging -> m a) ->
  m a
-- 1. No file logging
withMLogging :: forall (m :: Type -> Type) a.
(HasCallStack, MonadAtomic m, MonadFileWriter m,
 MonadHandleWriter m, MonadMask m, MonadPathReader m,
 MonadPathWriter m, MonadPosixFiles m, MonadTerminal m) =>
Maybe FileLoggingMerged -> (MLogging -> m a) -> m a
withMLogging Maybe FileLoggingMerged
Nothing MLogging -> m a
onLogging = MLogging -> m a
onLogging MLogging
forall a. Maybe a
Nothing
-- 2. Use the default path.
withMLogging (Just FileLoggingMerged
fileLogging) MLogging -> m a
onLogging = do
  let fileMode :: FileMode
fileMode = FileLoggingMerged
fileLogging FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileMode -> FileMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileMode
#mode
      ioMode :: Bool
ioMode = FileMode -> Bool
FileMode.toIOMode FileMode
fileMode

  OsPath
fp <- case FileLoggingMerged
fileLogging FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FilePathDefault
-> FilePathDefault
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
#file Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
-> Optic
     A_Lens
     NoIx
     FileLogInitMerged
     FileLogInitMerged
     FilePathDefault
     FilePathDefault
-> Optic' A_Lens NoIx FileLoggingMerged FilePathDefault
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitMerged
  FileLogInitMerged
  FilePathDefault
  FilePathDefault
#path of
    FilePathDefault
FPDefault -> do
      OsPath
stateDir <- m OsPath
forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m) =>
m OsPath
getShrunXdgState
      let fp :: OsPath
fp = OsPath
stateDir OsPath -> OsPath -> OsPath
</> [osp|shrun.log|]
      Bool
stateExists <- OsPath -> m Bool
forall (m :: Type -> Type).
(MonadPathReader m, HasCallStack) =>
OsPath -> m Bool
doesDirectoryExist OsPath
stateDir
      Bool -> m () -> m ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
unless Bool
stateExists (Bool -> OsPath -> m ()
forall (m :: Type -> Type).
(MonadPathWriter m, HasCallStack) =>
Bool -> OsPath -> m ()
createDirectoryIfMissing Bool
True OsPath
stateDir)
      pure OsPath
fp
    FPManual OsPath
fp -> OsPath -> m OsPath
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure OsPath
fp

  OsPath
uniqFp <- FileMode -> OsPath -> m OsPath
forall (m :: Type -> Type).
(HasCallStack, MonadFileWriter m, MonadHandleWriter m,
 MonadPathReader m, MonadPosixFiles m, MonadThrow m) =>
FileMode -> OsPath -> m OsPath
createLogFile FileMode
fileMode OsPath
fp
  FileSizeMode -> OsPath -> m ()
forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m, MonadPathWriter m,
 MonadTerminal m) =>
FileSizeMode -> OsPath -> m ()
handleLogFileSize (FileLoggingMerged
fileLogging FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged FileSizeMode
-> FileSizeMode
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
#file Optic
  A_Lens
  NoIx
  FileLoggingMerged
  FileLoggingMerged
  FileLogInitMerged
  FileLogInitMerged
-> Optic
     A_Lens
     NoIx
     FileLogInitMerged
     FileLogInitMerged
     FileSizeMode
     FileSizeMode
-> Optic' A_Lens NoIx FileLoggingMerged FileSizeMode
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  A_Lens
  NoIx
  FileLogInitMerged
  FileLogInitMerged
  FileSizeMode
  FileSizeMode
#sizeMode) OsPath
uniqFp
  TBQueue FileLog
fileQueue <- Natural -> m (TBQueue FileLog)
forall (m :: Type -> Type) a.
(HasCallStack, MonadAtomic m) =>
Natural -> m (TBQueue a)
newTBQueueA Natural
1000

  Maybe (TVar Word16)
mMultiCounter <-
    if FileLoggingMerged
fileLogging FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged Bool -> Bool
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged FileLogMultiSwitch
#multi Optic' A_Lens NoIx FileLoggingMerged FileLogMultiSwitch
-> Optic
     An_Iso NoIx FileLogMultiSwitch FileLogMultiSwitch Bool Bool
-> Optic' A_Lens NoIx FileLoggingMerged Bool
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic An_Iso NoIx FileLogMultiSwitch FileLogMultiSwitch Bool Bool
#unFileLogMultiSwitch
      then TVar Word16 -> Maybe (TVar Word16)
forall a. a -> Maybe a
Just (TVar Word16 -> Maybe (TVar Word16))
-> m (TVar Word16) -> m (Maybe (TVar Word16))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Word16 -> m (TVar Word16)
forall (m :: Type -> Type) a.
(HasCallStack, MonadAtomic m) =>
a -> m (TVar a)
newTVarA' Word16
1
      else Maybe (TVar Word16) -> m (Maybe (TVar Word16))
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Maybe (TVar Word16)
forall a. Maybe a
Nothing

  a
result <-
    OsPath -> Bool -> (Handle 'HandleModeWrite -> m a) -> m a
forall a.
HasCallStack =>
OsPath -> Bool -> (Handle 'HandleModeWrite -> m a) -> m a
forall (m :: Type -> Type) a.
(MonadHandleWriter m, HasCallStack) =>
OsPath -> Bool -> (Handle 'HandleModeWrite -> m a) -> m a
withBinaryFile OsPath
uniqFp Bool
ioMode ((Handle 'HandleModeWrite -> m a) -> m a)
-> (Handle 'HandleModeWrite -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \Handle 'HandleModeWrite
h -> Handle 'HandleModeWrite -> (LockedHandleW -> m a) -> m a
forall (p :: HandleMode) (m :: Type -> Type) a.
(CanWrite p, HasCallStack, MonadHandleWriter m, MonadMask m) =>
Handle p -> (LockedHandle p -> m a) -> m a
withLockedFile Handle 'HandleModeWrite
h ((LockedHandleW -> m a) -> m a) -> (LockedHandleW -> m a) -> m a
forall a b. (a -> b) -> a -> b
$ \LockedHandleW
lh ->
      MLogging -> m a
onLogging ((FileLoggingMerged, LockedHandleW, OsPath, TBQueue FileLog,
 Maybe (TVar Word16))
-> MLogging
forall a. a -> Maybe a
Just (FileLoggingMerged
fileLogging, LockedHandleW
lh, OsPath
uniqFp, TBQueue FileLog
fileQueue, Maybe (TVar Word16)
mMultiCounter))

  -- If the above command succeeded and deleteOnSuccess is true, delete the
  -- log file. Otherwise we will not reach here due to withBinaryFile
  -- rethrowing an exception, so the file will not be deleted.
  Bool -> m () -> m ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (FileLoggingMerged
fileLogging FileLoggingMerged
-> Optic' A_Lens NoIx FileLoggingMerged Bool -> Bool
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx FileLoggingMerged DeleteOnSuccessSwitch
#deleteOnSuccess Optic' A_Lens NoIx FileLoggingMerged DeleteOnSuccessSwitch
-> Optic
     An_Iso NoIx DeleteOnSuccessSwitch DeleteOnSuccessSwitch Bool Bool
-> Optic' A_Lens NoIx FileLoggingMerged Bool
forall k l m (is :: IxList) (js :: IxList) (ks :: IxList) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% Optic
  An_Iso NoIx DeleteOnSuccessSwitch DeleteOnSuccessSwitch Bool Bool
#unDeleteOnSuccessSwitch)
    (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ OsPath -> m ()
forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m, MonadPathWriter m) =>
OsPath -> m ()
removeFileIfExists_ OsPath
uniqFp

  pure a
result
{-# INLINEABLE withMLogging #-}

handleLogFileSize ::
  ( HasCallStack,
    MonadPathReader m,
    MonadPathWriter m,
    MonadTerminal m
  ) =>
  FileSizeMode ->
  OsPath ->
  m ()
handleLogFileSize :: forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m, MonadPathWriter m,
 MonadTerminal m) =>
FileSizeMode -> OsPath -> m ()
handleLogFileSize FileSizeMode
fileSizeMode OsPath
fp = do
  Bytes 'B Natural
fileSize <- forall (s :: Size) n. n -> Bytes s n
MkBytes @B (Natural -> Bytes 'B Natural)
-> (Integer -> Natural) -> Integer -> Bytes 'B Natural
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
. Integer -> Natural
forall a b.
(Bits a, Bits b, HasCallStack, Integral a, Integral b, Show a,
 Typeable a, Typeable b) =>
a -> b
unsafeConvertIntegral (Integer -> Bytes 'B Natural) -> m Integer -> m (Bytes 'B Natural)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> OsPath -> m Integer
forall (m :: Type -> Type).
(MonadPathReader m, HasCallStack) =>
OsPath -> m Integer
getFileSize OsPath
fp
  case FileSizeMode
fileSizeMode of
    FileSizeModeWarn Bytes 'B Natural
warnSize ->
      Bool -> m () -> m ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Bytes 'B Natural
fileSize Bytes 'B Natural -> Bytes 'B Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Bytes 'B Natural
warnSize)
        (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ Text -> m ()
forall (m :: Type -> Type).
(HasCallStack, MonadTerminal m) =>
Text -> m ()
putTextLn
        (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Bytes 'B Natural -> Bytes 'B Natural -> Text
sizeWarning Bytes 'B Natural
warnSize Bytes 'B Natural
fileSize
    FileSizeModeDelete Bytes 'B Natural
delSize ->
      Bool -> m () -> m ()
forall (f :: Type -> Type). Applicative f => Bool -> f () -> f ()
when (Bytes 'B Natural
fileSize Bytes 'B Natural -> Bytes 'B Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Bytes 'B Natural
delSize) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
        Text -> m ()
forall (m :: Type -> Type).
(HasCallStack, MonadTerminal m) =>
Text -> m ()
putTextLn (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Bytes 'B Natural -> Bytes 'B Natural -> Text
sizeWarning Bytes 'B Natural
delSize Bytes 'B Natural
fileSize Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" Deleting log."
        OsPath -> m ()
forall (m :: Type -> Type).
(MonadPathWriter m, HasCallStack) =>
OsPath -> m ()
removeFile OsPath
fp
    FileSizeMode
FileSizeModeNothing -> () -> m ()
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure ()
  where
    sizeWarning :: Bytes 'B Natural -> Bytes 'B Natural -> Text
sizeWarning Bytes 'B Natural
warnSize Bytes 'B Natural
fileSize =
      [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
        [ Text
"Warning: log file '",
          String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ OsPath -> String
decodeLenient OsPath
fp,
          Text
"' has size: ",
          Bytes 'B Natural -> Text
formatBytes Bytes 'B Natural
fileSize,
          Text
", but specified threshold is: ",
          Bytes 'B Natural -> Text
formatBytes Bytes 'B Natural
warnSize,
          Text
"."
        ]

    formatBytes :: Bytes 'B Natural -> Text
formatBytes =
      BaseFormatter (Raw (Norm (Bytes 'B Double)))
-> SizedFormatter -> Norm (Bytes 'B Double) -> Text
forall a.
(Formatter (BaseFormatter (Raw a)), PrintfArg (Raw a),
 RawNumeric a, Sized a) =>
BaseFormatter (Raw a) -> SizedFormatter -> a -> Text
formatSized (Maybe Word8 -> FloatingFormatter
MkFloatingFormatter (Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
2)) SizedFormatter
sizedFormatterNatural
        (Norm (Bytes 'B Double) -> Text)
-> (Bytes 'B Natural -> Norm (Bytes 'B Double))
-> Bytes 'B Natural
-> Text
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
. Bytes 'B Double -> Norm (Bytes 'B Double)
forall a. Normalize a => a -> Norm a
normalize
        -- Convert to double _before_ normalizing. We may lose some precision
        -- here, but it is better than normalizing a natural, which will
        -- truncate (i.e. greater precision loss).
        (Bytes 'B Double -> Norm (Bytes 'B Double))
-> (Bytes 'B Natural -> Bytes 'B Double)
-> Bytes 'B Natural
-> Norm (Bytes 'B Double)
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
. (Natural -> Double) -> Bytes 'B Natural -> Bytes 'B Double
forall a b. (a -> b) -> Bytes 'B a -> Bytes 'B b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer -> Double
toDouble (Integer -> Double) -> (Natural -> Integer) -> Natural -> Double
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
. Natural -> Integer
forall a b.
(Bits a, Bits b, HasCallStack, Integral a, Integral b, Show a,
 Typeable a, Typeable b) =>
a -> b
unsafeConvertIntegral)

    toDouble :: Integer -> Double
    toDouble :: Integer -> Double
toDouble = Integer -> Double
forall a. (Fromℤ a, HasCallStack) => Integer -> a
fromℤ
{-# INLINEABLE handleLogFileSize #-}

-- | Ensures the given path exists. If the path already exists and the file
-- mode is FileModeRename, we rename the new path sequentially, to avoid
-- a collision.
createLogFile ::
  ( HasCallStack,
    MonadFileWriter m,
    MonadHandleWriter m,
    MonadPathReader m,
    MonadPosixFiles m,
    MonadThrow m
  ) =>
  -- | Mode in which to open the new log file.
  FileMode ->
  -- | Full path of the desired file.
  OsPath ->
  m OsPath
createLogFile :: forall (m :: Type -> Type).
(HasCallStack, MonadFileWriter m, MonadHandleWriter m,
 MonadPathReader m, MonadPosixFiles m, MonadThrow m) =>
FileMode -> OsPath -> m OsPath
createLogFile FileMode
mode fp :: OsPath
fp@(OsString PosixString
posixPath) = do
  Bool
exists <- OsPath -> m Bool
forall (m :: Type -> Type).
(MonadPathReader m, HasCallStack) =>
OsPath -> m Bool
PR.doesPathExist OsPath
fp
  -- 1. Requested log path exists.
  if Bool
exists
    then do
      PosixString -> m PathType
forall (m :: Type -> Type).
(HasCallStack, MonadPosixFiles m) =>
PosixString -> m PathType
PosixFiles.getPathType PosixString
posixPath m PathType -> (PathType -> m OsPath) -> m OsPath
forall a b. m a -> (a -> m b) -> m b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        -- 1.1. Log path is an extant file.
        PathType
PathTypeFile -> case FileMode
mode of
          -- 1.1.1. Rename mode: Find new name and create.
          FileMode
FileModeRename -> do
            OsPath
newFp <- OsPath -> m OsPath
forall (m :: Type -> Type).
(HasCallStack, MonadHandleWriter m, MonadPathReader m,
 MonadThrow m) =>
OsPath -> m OsPath
uniqName OsPath
fp
            OsPath -> m OsPath
forall {f :: Type -> Type}. MonadFileWriter f => OsPath -> f OsPath
writeBlankFile OsPath
newFp
          -- 1.1.2. Write or Append mode: Fine, nothing to do.
          FileMode
_ -> OsPath -> m OsPath
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure OsPath
fp
        -- 1.2. Log path is an extant non-file (directory, symlink): Error.
        -- Technically this already errors elsewhere (presumably withFile),
        -- but we can provide another check here out of paranoia and include
        -- a better error message.
        PathType
otherPathType -> do
          Text -> m OsPath
forall (m :: Type -> Type) a.
(HasCallStack, MonadThrow m) =>
Text -> m a
throwText
            (Text -> m OsPath) -> Text -> m OsPath
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
              [ Text
"Requested log file '",
                String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ OsPath -> String
decodeLenient OsPath
fp,
                Text
"' already exists and has invalid type: ",
                PathType -> Text
forall a. IsString a => PathType -> a
PT.displayPathType PathType
otherPathType,
                Text
"."
              ]
    -- 2. Log path does not exist: Create.
    else OsPath -> m OsPath
forall {f :: Type -> Type}. MonadFileWriter f => OsPath -> f OsPath
writeBlankFile OsPath
fp
  where
    writeBlankFile :: OsPath -> f OsPath
writeBlankFile OsPath
p = OsPath -> Text -> f ()
forall (m :: Type -> Type).
(HasCallStack, MonadFileWriter m) =>
OsPath -> Text -> m ()
writeFileUtf8 OsPath
p Text
"" f () -> OsPath -> f OsPath
forall (f :: Type -> Type) a b. Functor f => f a -> b -> f b
$> OsPath
p
{-# INLINEABLE createLogFile #-}

uniqName ::
  forall m.
  ( HasCallStack,
    MonadHandleWriter m,
    MonadPathReader m,
    MonadThrow m
  ) =>
  OsPath ->
  m OsPath
uniqName :: forall (m :: Type -> Type).
(HasCallStack, MonadHandleWriter m, MonadPathReader m,
 MonadThrow m) =>
OsPath -> m OsPath
uniqName OsPath
fp = Word16 -> m OsPath
go Word16
1
  where
    (OsPath
base, OsPath
ext) = OsPath -> (OsPath, OsPath)
OsPath.splitExtension OsPath
fp

    appendNum :: OsPath -> OsPath
appendNum OsPath
c = OsPath
base OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> [osp| (|] OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> OsPath
c OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> [osp|)|] OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> OsPath
ext

    go :: Word16 -> m OsPath
    go :: Word16 -> m OsPath
go !Word16
counter
      | Word16
counter Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
== Word16
forall a. Bounded a => a
maxBound = String -> m OsPath
forall (m :: Type -> Type) a.
(HasCallStack, MonadHandleWriter m, MonadThrow m) =>
String -> m a
die (String -> m OsPath) -> String -> m OsPath
forall a b. (a -> b) -> a -> b
$ String
"Failed renaming file: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> OsPath -> String
forall a. Show a => a -> String
show OsPath
fp
      | Bool
otherwise = do
          OsPath
newFp <- OsPath -> OsPath
appendNum (OsPath -> OsPath) -> m OsPath -> m OsPath
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> m OsPath
forall (m :: Type -> Type).
(HasCallStack, MonadThrow m) =>
String -> m OsPath
encodeThrowM (Word16 -> String
forall a. Show a => a -> String
show Word16
counter)
          Bool
b <- OsPath -> m Bool
forall (m :: Type -> Type).
(MonadPathReader m, HasCallStack) =>
OsPath -> m Bool
PR.doesPathExist OsPath
newFp
          if Bool
b
            then Word16 -> m OsPath
go (Word16
counter Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ Word16
1)
            else OsPath -> m OsPath
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure OsPath
newFp

-- | Like 'createLogFile', but for multi logs, which has different semantics.
--
-- While we allow overwriting / appending to existing files, what we absolutely
-- do /not/ want to allow is two shrun commands actively logging to the
-- /same/ file. This would mean logs get jumbled up.
--
-- Therefore, if we encounter an extant file, we use the TVar counter to append
-- a number. This index is unique across all shrun commands, hence we will
-- not have interference.
createMultiLogFile ::
  forall m.
  ( HasCallStack,
    MonadAtomic m,
    MonadHandleWriter m,
    MonadPathReader m,
    MonadPosixFiles m,
    MonadThrow m
  ) =>
  TVar Word16 ->
  FileMode ->
  OsPath ->
  m OsPath
createMultiLogFile :: forall (m :: Type -> Type).
(HasCallStack, MonadAtomic m, MonadHandleWriter m,
 MonadPathReader m, MonadPosixFiles m, MonadThrow m) =>
TVar Word16 -> FileMode -> OsPath -> m OsPath
createMultiLogFile TVar Word16
counterRef FileMode
mode fp :: OsPath
fp@(OsString PosixString
posixPath) = m OsPath
go
  where
    (OsPath
base, OsPath
ext) = OsPath -> (OsPath, OsPath)
OsPath.splitExtension OsPath
fp

    appendNum :: OsPath -> OsPath
appendNum OsPath
c = OsPath
base OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> [osp|_multi|] OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> OsPath
c OsPath -> OsPath -> OsPath
forall a. Semigroup a => a -> a -> a
<> OsPath
ext

    go :: m OsPath
    go :: m OsPath
go = do
      Word16
counter <- STM Word16 -> m Word16
forall a. HasCallStack => STM a -> m a
forall (m :: Type -> Type) a.
(MonadAtomic m, HasCallStack) =>
STM a -> m a
atomically (STM Word16 -> m Word16) -> STM Word16 -> m Word16
forall a b. (a -> b) -> a -> b
$ TVar Word16 -> STM Word16
Utils.readIncCounter TVar Word16
counterRef
      if Word16
counter Word16 -> Word16 -> Bool
forall a. Eq a => a -> a -> Bool
== Word16
forall a. Bounded a => a
maxBound
        then String -> m OsPath
forall (m :: Type -> Type) a.
(HasCallStack, MonadHandleWriter m, MonadThrow m) =>
String -> m a
die (String -> m OsPath) -> String -> m OsPath
forall a b. (a -> b) -> a -> b
$ String
"Failed naming file: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> OsPath -> String
forall a. Show a => a -> String
show OsPath
fp
        else do
          OsPath
newFp <- OsPath -> OsPath
appendNum (OsPath -> OsPath) -> m OsPath -> m OsPath
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> m OsPath
forall (m :: Type -> Type).
(HasCallStack, MonadThrow m) =>
String -> m OsPath
encodeThrowM (Word16 -> String
forall a. Show a => a -> String
show Word16
counter)
          Bool
exists <- OsPath -> m Bool
forall (m :: Type -> Type).
(MonadPathReader m, HasCallStack) =>
OsPath -> m Bool
PR.doesPathExist OsPath
newFp
          if Bool
exists
            then do
              PosixString -> m PathType
forall (m :: Type -> Type).
(HasCallStack, MonadPosixFiles m) =>
PosixString -> m PathType
PosixFiles.getPathType PosixString
posixPath m PathType -> (PathType -> m OsPath) -> m OsPath
forall a b. m a -> (a -> m b) -> m b
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                -- 1.1. Log path is an extant file.
                PathType
PathTypeFile -> OsPath -> m OsPath
onFile OsPath
newFp
                -- 1.2. Log path is an extant non-file (directory, symlink):
                -- Recurse to try a new name.
                PathType
_otherPathType -> m OsPath
go
            -- File does not exist; nothing to do.
            else OsPath -> m OsPath
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure OsPath
newFp

    onFile :: OsPath -> m OsPath
onFile = case FileMode
mode of
      -- Rename mode: Recurse to find a new name.
      FileMode
FileModeRename -> m OsPath -> OsPath -> m OsPath
forall a b. a -> b -> a
const m OsPath
go
      -- Write or Append mode: Fine, return the path.
      FileMode
_otherMode -> OsPath -> m OsPath
forall a. a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure
{-# INLINEABLE createMultiLogFile #-}

getShrunXdgState :: (HasCallStack, MonadPathReader m) => m OsPath
getShrunXdgState :: forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m) =>
m OsPath
getShrunXdgState = OsPath -> m OsPath
forall (m :: Type -> Type).
(HasCallStack, MonadPathReader m) =>
OsPath -> m OsPath
getXdgState [osp|shrun|]
{-# INLINEABLE getShrunXdgState #-}

defaultToml :: FileLoggingToml
defaultToml :: FileLoggingToml
defaultToml =
  MkFileLoggingP
    { file :: FileLogFileF 'ConfigPhaseToml
file =
        MkFileLogInitP
          { path :: FileLogPathF 'ConfigPhaseToml
path = Maybe (WithDisabled FilePathDefault)
FileLogPathF 'ConfigPhaseToml
forall a. Maybe a
Nothing,
            sizeMode :: ConfigPhaseF 'ConfigPhaseToml FileSizeMode
sizeMode = Maybe FileSizeMode
ConfigPhaseF 'ConfigPhaseToml FileSizeMode
forall a. Maybe a
Nothing
          },
      commandNameTrunc :: ConfigPhaseDisabledMaybeF
  'ConfigPhaseToml (Truncation 'TruncCommandName)
commandNameTrunc = Maybe (WithDisabled (Truncation 'TruncCommandName))
ConfigPhaseDisabledMaybeF
  'ConfigPhaseToml (Truncation 'TruncCommandName)
forall a. Maybe a
Nothing,
      deleteOnSuccess :: SwitchF 'ConfigPhaseToml DeleteOnSuccessSwitch
deleteOnSuccess = Maybe DeleteOnSuccessSwitch
SwitchF 'ConfigPhaseToml DeleteOnSuccessSwitch
forall a. Maybe a
Nothing,
      lineTrunc :: LineTruncF 'ConfigPhaseToml
lineTrunc = Maybe (WithDisabled LineTruncation)
LineTruncF 'ConfigPhaseToml
forall a. Maybe a
Nothing,
      mode :: ConfigPhaseF 'ConfigPhaseToml FileMode
mode = Maybe FileMode
ConfigPhaseF 'ConfigPhaseToml FileMode
forall a. Maybe a
Nothing,
      multi :: FileLogMultiF 'ConfigPhaseToml
multi = Maybe FileLogMultiSwitch
FileLogMultiF 'ConfigPhaseToml
forall a. Maybe a
Nothing,
      stripControl :: ConfigPhaseF 'ConfigPhaseToml FileLogStripControl
stripControl = Maybe FileLogStripControl
ConfigPhaseF 'ConfigPhaseToml FileLogStripControl
forall a. Maybe a
Nothing
    }