{-# LANGUAGE NoImplicitPrelude #-}

{-|
Module      : Headroom.HeaderFn.Types
Description : Data types for /license header functions/
Copyright   : (c) 2019-2020 Vaclav Svejcar
License     : BSD-3-Clause
Maintainer  : vaclav.svejcar@gmail.com
Stability   : experimental
Portability : POSIX

This module contains data types and /type class/ instances for the
/license header functions/.
-}

module Headroom.HeaderFn.Types
  ( HeaderFn(..)
  )
where

import           RIO


-- | Definition of /license header function/, i.e. function, that is applied to
-- already rendered /license header/, performs some logic and returns modified
-- text of /license header/. Given that the /reader monad/ and 'ReaderT'
-- transformer is used, any configuration is provided using the @env@
-- environment. When combined with the "Headroom.Data.Has" monad, it provides
-- powerful way how to combine different /license header function/ and
-- environments.
--
-- = Structure of License Header Function Type
--
-- @
-- __Text -> Reader env Text__
--   │              │   │
--   └─ rendered text of license header
--                  │   │
--                  └─ environment holding possible configuration
--                      │
--                      └─ modified license header text
-- @
newtype HeaderFn env = HeaderFn (Text -> Reader env Text)

instance Semigroup (HeaderFn env) where
  HeaderFn Text -> Reader env Text
fnX <> :: HeaderFn env -> HeaderFn env -> HeaderFn env
<> HeaderFn Text -> Reader env Text
fnY = (Text -> Reader env Text) -> HeaderFn env
forall env. (Text -> Reader env Text) -> HeaderFn env
HeaderFn ((Text -> Reader env Text) -> HeaderFn env)
-> (Text -> Reader env Text) -> HeaderFn env
forall a b. (a -> b) -> a -> b
$ Text -> Reader env Text
fnX (Text -> Reader env Text)
-> (Text -> Reader env Text) -> Text -> Reader env Text
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Text -> Reader env Text
fnY

instance Monoid (HeaderFn env) where
  mempty :: HeaderFn env
mempty = (Text -> Reader env Text) -> HeaderFn env
forall env. (Text -> Reader env Text) -> HeaderFn env
HeaderFn ((Text -> Reader env Text) -> HeaderFn env)
-> (Text -> Reader env Text) -> HeaderFn env
forall a b. (a -> b) -> a -> b
$ \Text
input -> Text -> Reader env Text
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
input