filepather-0.8.0.0: src/System/FilePather/Step.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}
{- | One application of a named build step to a file.
A 'Step' is a product: its fields are named 'stepName' and 'stepInput'.
-}
module System.FilePather.Step (
-- * Type
Step (..),
-- * Optics
StepLike (..),
lawNamesStep,
InheritStep,
inheritStep,
) where
import Control.DeepSeq (NFData)
import Control.Lens (Optic, cloneLens, view)
import Data.Data (Data)
import Data.Functor.Const (Const)
import GHC.Generics (Generic)
import System.FilePather.Name.StepInput (StepInputLike (..))
import System.FilePather.Name.StepName (StepNameLike (..))
{- $setup
>>> import Control.Lens (cloneLens, view)
-}
{- | One application of a named build step to a file: the name of the step
('stepName'), such as @"pdf page 1"@, and its input file ('stepInput').
>>> view (cloneLens stepName) (Step "pdf page 1" "public/a.pdf")
"pdf page 1"
>>> view (cloneLens stepInput) (Step "pdf page 1" "public/a.pdf")
"public/a.pdf"
@since 0.7.0.0
-}
data Step
= Step String FilePath
deriving stock (Eq, Ord, Show, Generic, Data)
deriving anyclass (NFData)
{- | The class of 'Step'.
@since 0.8.0.0
-}
class StepLike p f x x' where
step ::
Optic p f x x' Step Step
{- | Identity
@since 0.8.0.0
-}
instance (x' ~ Step) => StepLike p f Step x' where
step =
id
{-# INLINE step #-}
{- | Lens
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ Step) => StepNameLike p f Step x' where
stepName f (Step n i) =
fmap (`Step` i) (f n)
{-# INLINE stepName #-}
{- | Lens
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ Step) => StepInputLike p f Step x' where
stepInput f (Step n i) =
fmap (Step n) (f i)
{-# INLINE stepInput #-}
{- | Rebuild a value using only the name of each field.
Laws:
> lawNamesStep == id
@since 0.8.0.0
-}
lawNamesStep :: Step -> Step
lawNamesStep s =
Step (view (cloneLens stepName) s) (view (cloneLens stepInput) s)
{- | The classes that a data type holding 'Step' inherits.
@since 0.8.0.0
-}
type InheritStep s =
( StepLike (->) (Const ()) s s
, StepNameLike (->) (Const ()) s s
, StepInputLike (->) (Const ()) s s
)
{- | Check, where it is applied, that @s@ inherits every name of 'Step'.
@since 0.8.0.0
-}
inheritStep :: (InheritStep s) => proxy s -> ()
inheritStep _ =
()