packages feed

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

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

{- | A file that does not contain strings it is required to contain.

A 'StringsMissing' is a product: its fields are named 'file' and 'missingStrings'.
-}
module Document.Build.Error.StringsMissing (
  -- * Type
  StringsMissing (..),

  -- * Optics
  StringsMissingLike (..),
  lawNamesStringsMissing,
  InheritStringsMissing,
  inheritStringsMissing,
) where

import Control.DeepSeq (NFData)
import Control.Lens (Optic, cloneLens, view)
import Data.Data (Data)
import Data.Functor.Const (Const)
import Data.List.NonEmpty (NonEmpty)
import Document.Build.Name.MissingStrings (MissingStringsLike (..))
import GHC.Generics (Generic)
import System.FilePather.Name.File (FileLike (..))

{- | A file ('file') does not contain strings it is required to contain ('missingStrings').

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

{- | The class of 'StringsMissing'.

@since 0.2.0.0
-}
class StringsMissingLike p f x x' where
  stringsMissing ::
    Optic p f x x' StringsMissing StringsMissing

{- | Identity

@since 0.2.0.0
-}
instance (x' ~ StringsMissing) => StringsMissingLike p f StringsMissing x' where
  stringsMissing =
    id
  {-# INLINE stringsMissing #-}

{- | Lens

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

{- | Lens

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

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

Laws:

> lawNamesStringsMissing == id

@since 0.2.0.0
-}
lawNamesStringsMissing :: StringsMissing -> StringsMissing
lawNamesStringsMissing s =
  StringsMissing
    (view (cloneLens file) s)
    (view (cloneLens missingStrings) s)

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

@since 0.2.0.0
-}
type InheritStringsMissing s =
  ( StringsMissingLike (->) (Const ()) s s
  , FileLike (->) (Const ()) s s
  , MissingStringsLike (->) (Const ()) s s
  )

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

@since 0.2.0.0
-}
inheritStringsMissing :: (InheritStringsMissing s) => proxy s -> ()
inheritStringsMissing _ =
  ()