packages feed

document-build-0.2.0.0: src/Document/Build/Error/OutputFileMissing.hs

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}

{- | A process that did not produce an output file it should have.

A 'OutputFileMissing' is a product: its fields are named 'commandLine' and 'file'.
It holds 'CommandLine', so it inherits its names.
-}
module Document.Build.Error.OutputFileMissing (
  -- * Type
  OutputFileMissing (..),

  -- * Optics
  OutputFileMissingLike (..),
  lawNamesOutputFileMissing,
  InheritOutputFileMissing,
  inheritOutputFileMissing,
  inheritsOutputFileMissing,
) where

import Control.DeepSeq (NFData)
import Control.Lens (Optic, cloneLens, view)
import Data.Data (Data)
import Data.Functor.Const (Const)
import Data.Proxy (Proxy (..))
import Document.Build.CommandLine (CommandLine, CommandLineLike (..), inheritCommandLine)
import Document.Build.Name.CommandLineArguments (CommandLineArgumentsLike (..))
import Document.Build.Name.CommandLineProgram (CommandLineProgramLike (..))
import GHC.Generics (Generic)
import System.FilePather.Name.File (FileLike (..))

{- | A process succeeded, but did not produce an output file it should have: its command
line ('commandLine'), and the file ('file').

@since 0.2.0.0
-}
data OutputFileMissing
  = OutputFileMissing CommandLine FilePath
  deriving stock (Eq, Ord, Show, Generic, Data)
  deriving anyclass (NFData)

{- | The class of 'OutputFileMissing'.

@since 0.2.0.0
-}
class OutputFileMissingLike p f x x' where
  outputFileMissing ::
    Optic p f x x' OutputFileMissing OutputFileMissing

{- | Identity

@since 0.2.0.0
-}
instance (x' ~ OutputFileMissing) => OutputFileMissingLike p f OutputFileMissing x' where
  outputFileMissing =
    id
  {-# INLINE outputFileMissing #-}

{- | Lens: 'commandLine' is the default name of the field of type 'CommandLine'.

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ OutputFileMissing) => CommandLineLike p f OutputFileMissing x' where
  commandLine f (OutputFileMissing x1 x2) =
    fmap (`OutputFileMissing` x2) (f x1)
  {-# INLINE commandLine #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ OutputFileMissing) => FileLike p f OutputFileMissing x' where
  file f (OutputFileMissing x1 x2) =
    fmap (OutputFileMissing x1) (f x2)
  {-# INLINE file #-}

{- | Lens: through 'commandLine', a lens, then 'CommandLine''s 'commandLineProgram', a lens.

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ OutputFileMissing) => CommandLineProgramLike p f OutputFileMissing x' where
  commandLineProgram =
    commandLine . commandLineProgram
  {-# INLINE commandLineProgram #-}

{- | Lens: through 'commandLine', a lens, then 'CommandLine''s 'commandLineArguments', a lens.

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ OutputFileMissing) => CommandLineArgumentsLike p f OutputFileMissing x' where
  commandLineArguments =
    commandLine . commandLineArguments
  {-# INLINE commandLineArguments #-}

{- | Rebuild a value using only the name of each field.

Laws:

> lawNamesOutputFileMissing == id

@since 0.2.0.0
-}
lawNamesOutputFileMissing :: OutputFileMissing -> OutputFileMissing
lawNamesOutputFileMissing s =
  OutputFileMissing
    (view (cloneLens commandLine) s)
    (view (cloneLens file) s)

{- | The classes that a data type holding 'OutputFileMissing' inherits.

@since 0.2.0.0
-}
type InheritOutputFileMissing s =
  ( OutputFileMissingLike (->) (Const ()) s s
  , CommandLineLike (->) (Const ()) s s
  , FileLike (->) (Const ()) s s
  , CommandLineProgramLike (->) (Const ()) s s
  , CommandLineArgumentsLike (->) (Const ()) s s
  )

{- | Check, where it is applied, that @s@ inherits every name of 'OutputFileMissing'.

@since 0.2.0.0
-}
inheritOutputFileMissing :: (InheritOutputFileMissing s) => proxy s -> ()
inheritOutputFileMissing _ =
  ()

{- | 'OutputFileMissing' inherits every name of 'CommandLine'.

@since 0.2.0.0
-}
inheritsOutputFileMissing :: [()]
inheritsOutputFileMissing =
  let p = Proxy :: Proxy OutputFileMissing
   in [inheritCommandLine p]