packages feed

document-build-0.2.0.0: src/Document/Build/GitDetails.hs

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

{- | Details of the last commit to change a file.

A 'GitDetails' is a product: its fields are named 'gitCommitHash', 'gitCommitHashShort', 'gitAuthorName', 'gitAuthorEmail', 'gitAuthorTime', 'gitCommitterName', 'gitCommitterEmail', 'gitCommitTime', 'gitSubject' and 'gitAuthors'.
-}
module Document.Build.GitDetails (
  -- * Type
  GitDetails (..),

  -- * Optics
  GitDetailsLike (..),
  lawNamesGitDetails,
  InheritGitDetails,
  inheritGitDetails,
) where

import Control.DeepSeq (NFData)
import Control.Lens (Optic, cloneLens, view)
import Data.Aeson (FromJSON (..), ToJSON (..), object, withObject, (.:), (.=))
import Data.Data (Data)
import Data.Functor.Const (Const)
import Data.Time (UTCTime)
import Document.Build.Name.GitAuthorEmail (GitAuthorEmailLike (..))
import Document.Build.Name.GitAuthorName (GitAuthorNameLike (..))
import Document.Build.Name.GitAuthorTime (GitAuthorTimeLike (..))
import Document.Build.Name.GitAuthors (GitAuthorsLike (..))
import Document.Build.Name.GitCommitHash (GitCommitHashLike (..))
import Document.Build.Name.GitCommitHashShort (GitCommitHashShortLike (..))
import Document.Build.Name.GitCommitTime (GitCommitTimeLike (..))
import Document.Build.Name.GitCommitterEmail (GitCommitterEmailLike (..))
import Document.Build.Name.GitCommitterName (GitCommitterNameLike (..))
import Document.Build.Name.GitSubject (GitSubjectLike (..))
import GHC.Generics (Generic)

{- | Details of the last commit to change a file, and everyone who has
changed it: the commit hash ('gitCommitHash'), abbreviated commit hash
('gitCommitHashShort'), author name ('gitAuthorName'), author email
('gitAuthorEmail'), author time ('gitAuthorTime'), committer name
('gitCommitterName'), committer email ('gitCommitterEmail'), commit time
('gitCommitTime'), subject ('gitSubject'), and the authors of every commit to
change the file as @Name \<email\>@, most recent first, without duplicates
('gitAuthors').

@since 0.1.0.0
-}
data GitDetails
  = GitDetails String String String String UTCTime String String UTCTime String [String]
  deriving stock (Eq, Ord, Show, Generic, Data)
  deriving anyclass (NFData)

-- | @since 0.1.0.0
instance ToJSON GitDetails where
  toJSON (GitDetails h h' an ae at cn ce ct subject as) =
    object
      [ "hash" .= h
      , "hashShort" .= h'
      , "authorName" .= an
      , "authorEmail" .= ae
      , "authorTime" .= at
      , "committerName" .= cn
      , "committerEmail" .= ce
      , "commitTime" .= ct
      , "subject" .= subject
      , "authors" .= as
      ]

-- | @since 0.1.0.0
instance FromJSON GitDetails where
  parseJSON =
    withObject "GitDetails" $ \o ->
      GitDetails
        <$> o .: "hash"
        <*> o .: "hashShort"
        <*> o .: "authorName"
        <*> o .: "authorEmail"
        <*> o .: "authorTime"
        <*> o .: "committerName"
        <*> o .: "committerEmail"
        <*> o .: "commitTime"
        <*> o .: "subject"
        <*> o .: "authors"

{- | The class of 'GitDetails'.

@since 0.2.0.0
-}
class GitDetailsLike p f x x' where
  gitDetails ::
    Optic p f x x' GitDetails GitDetails

{- | Identity

@since 0.2.0.0
-}
instance (x' ~ GitDetails) => GitDetailsLike p f GitDetails x' where
  gitDetails =
    id
  {-# INLINE gitDetails #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitCommitHashLike p f GitDetails x' where
  gitCommitHash f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x1' -> GitDetails x1' x2 x3 x4 x5 x6 x7 x8 x9 x10) (f x1)
  {-# INLINE gitCommitHash #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitCommitHashShortLike p f GitDetails x' where
  gitCommitHashShort f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x2' -> GitDetails x1 x2' x3 x4 x5 x6 x7 x8 x9 x10) (f x2)
  {-# INLINE gitCommitHashShort #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitAuthorNameLike p f GitDetails x' where
  gitAuthorName f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x3' -> GitDetails x1 x2 x3' x4 x5 x6 x7 x8 x9 x10) (f x3)
  {-# INLINE gitAuthorName #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitAuthorEmailLike p f GitDetails x' where
  gitAuthorEmail f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x4' -> GitDetails x1 x2 x3 x4' x5 x6 x7 x8 x9 x10) (f x4)
  {-# INLINE gitAuthorEmail #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitAuthorTimeLike p f GitDetails x' where
  gitAuthorTime f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x5' -> GitDetails x1 x2 x3 x4 x5' x6 x7 x8 x9 x10) (f x5)
  {-# INLINE gitAuthorTime #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitCommitterNameLike p f GitDetails x' where
  gitCommitterName f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x6' -> GitDetails x1 x2 x3 x4 x5 x6' x7 x8 x9 x10) (f x6)
  {-# INLINE gitCommitterName #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitCommitterEmailLike p f GitDetails x' where
  gitCommitterEmail f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x7' -> GitDetails x1 x2 x3 x4 x5 x6 x7' x8 x9 x10) (f x7)
  {-# INLINE gitCommitterEmail #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitCommitTimeLike p f GitDetails x' where
  gitCommitTime f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x8' -> GitDetails x1 x2 x3 x4 x5 x6 x7 x8' x9 x10) (f x8)
  {-# INLINE gitCommitTime #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitSubjectLike p f GitDetails x' where
  gitSubject f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (\x9' -> GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9' x10) (f x9)
  {-# INLINE gitSubject #-}

{- | Lens

@since 0.2.0.0
-}
instance (p ~ (->), Functor f, x' ~ GitDetails) => GitAuthorsLike p f GitDetails x' where
  gitAuthors f (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9 x10) =
    fmap (GitDetails x1 x2 x3 x4 x5 x6 x7 x8 x9) (f x10)
  {-# INLINE gitAuthors #-}

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

Laws:

> lawNamesGitDetails == id

@since 0.2.0.0
-}
lawNamesGitDetails :: GitDetails -> GitDetails
lawNamesGitDetails s =
  GitDetails
    (view (cloneLens gitCommitHash) s)
    (view (cloneLens gitCommitHashShort) s)
    (view (cloneLens gitAuthorName) s)
    (view (cloneLens gitAuthorEmail) s)
    (view (cloneLens gitAuthorTime) s)
    (view (cloneLens gitCommitterName) s)
    (view (cloneLens gitCommitterEmail) s)
    (view (cloneLens gitCommitTime) s)
    (view (cloneLens gitSubject) s)
    (view (cloneLens gitAuthors) s)

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

@since 0.2.0.0
-}
type InheritGitDetails s =
  ( GitDetailsLike (->) (Const ()) s s
  , GitCommitHashLike (->) (Const ()) s s
  , GitCommitHashShortLike (->) (Const ()) s s
  , GitAuthorNameLike (->) (Const ()) s s
  , GitAuthorEmailLike (->) (Const ()) s s
  , GitAuthorTimeLike (->) (Const ()) s s
  , GitCommitterNameLike (->) (Const ()) s s
  , GitCommitterEmailLike (->) (Const ()) s s
  , GitCommitTimeLike (->) (Const ()) s s
  , GitSubjectLike (->) (Const ()) s s
  , GitAuthorsLike (->) (Const ()) s s
  )

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

@since 0.2.0.0
-}
inheritGitDetails :: (InheritGitDetails s) => proxy s -> ()
inheritGitDetails _ =
  ()