content: {- |
  Module                  : Toml.Codec.Combinator.Monoid
  Copyright               : (c) 2018-2022 Kowainik
  SPDX-License-Identifier : MPL-2.0
  Maintainer              : Kowainik <xrom.xkov@gmail.com>
  Stability               : Stable
  Portability             : Portable
  
  TOML-specific combinators for converting between TOML and Haskell 'Monoid'
  wrapper data types. These codecs are especially handy when you are implementing
  the [Partial Options Monoid](https://medium.com/@jonathangfischoff/the-partial-options-monoid-pattern-31914a71fc67)
  pattern.
  
  +-----------------------+------------+----------------------------+---------------------+
  |     Haskell Type      |   @TOML@   |        'TomlCodec'         | Default on          |
  |                       |            |                            | missing field       |
  +=======================+============+============================+=====================+
  | __'All'__             | @a = true@ | @'all' "a"@                | @'All' 'True'@      |
  +-----------------------+------------+----------------------------+---------------------+
  | __'Any'__             | @a = true@ | @'any' "a"@                | @'Any' 'False'@     |
  +-----------------------+------------+----------------------------+---------------------+
  | __@'Sum' 'Int'@__     | @a = 11@   | @'sum' 'Toml.int' "a"@     | @'Sum' 0@           |
  +-----------------------+------------+----------------------------+---------------------+
  | __@'Product' 'Int'@__ | @a = 11@   | @'product' 'Toml.int' "a"@ | @'Product' 1@       |
  +-----------------------+------------+----------------------------+---------------------+
  | __@'First' 'Int'@__   | @a = 42@   | @'first' 'Toml.int' "a"@   | @'First' 'Nothing'@ |
  +-----------------------+------------+----------------------------+---------------------+
  | __@'Last' 'Bool'@__   | @a = true@ | @'last' 'Toml.bool' "a"@   | @'Last' 'Nothing'@  |
  +-----------------------+------------+----------------------------+---------------------+
  
  @since 1.3.0.0
  -}
  
  module Toml.Codec.Combinator.Monoid
      ( -- * Codecs for 'Monoid's
        -- ** Bool wrappers
        all
      , any
        -- ** 'Num' wrappers
      , sum
      , product
        -- ** 'Maybe' wrappers
      , first
      , last
      ) where
  
  import Prelude hiding (all, any, last, product, sum)
  
  import Data.Monoid (All (..), Any (..), First (..), Last (..), Product (..), Sum (..))
  
  import Toml.Codec.Combinator.Primitive (bool)
  import Toml.Codec.Di (dimap, dioptional, diwrap)
  import Toml.Codec.Types (TomlCodec)
  import Toml.Type.Key (Key)
  
  
  {- | Codec for 'All' wrapper for boolean values.
  Returns @'All' 'True'@ on missing fields.
  
  Decodes to @'All' 'True'@ when the key is not present.
  
  @since 1.2.1.0
  -}
  all :: Key -> TomlCodec All
  all = dimap (Just . getAll) (maybe mempty All) . dioptional . bool
  {-# INLINE all #-}
  
  {- | Codec for 'Any' wrapper for boolean values.
  Returns @'Any' 'False'@ on missing fields.
  
  Decodes to @'Any' 'False'@ when the key is not present.
  
  @since 1.2.1.0
  -}
  any :: Key -> TomlCodec Any
  any = dimap (Just . getAny) (maybe mempty Any) . dioptional . bool
  {-# INLINE any #-}
  
  {- | Codec for 'Sum' wrapper for given converter's values.
  
  Decodes to @'Sum' 0@ when the key is not present.
  
  @since 1.2.1.0
  -}
  sum :: (Num a) => (Key -> TomlCodec a) -> Key -> TomlCodec (Sum a)
  sum codec = dimap (Just . getSum) (maybe mempty Sum) . dioptional . codec
  {-# INLINE sum #-}
  
  {- | Codec for 'Product' wrapper for given converter's values.
  
  Decodes to @'Product' 1@ when the key is not present.
  
  @since 1.2.1.0
  -}
  product :: (Num a) => (Key -> TomlCodec a) -> Key -> TomlCodec (Product a)
  product codec = dimap (Just . getProduct) (maybe mempty Product) . dioptional . codec
  {-# INLINE product #-}
  
  {- | Codec for 'First' wrapper for given converter's values.
  
  Decodes to @'First' 'Nothing'@ when the key is not present.
  
  @since 1.2.1.0
  -}
  first :: (Key -> TomlCodec a) -> Key -> TomlCodec (First a)
  first codec = diwrap . dioptional . codec
  {-# INLINE first #-}
  
  {- | Codec for 'Last' wrapper for given converter's values.
  
  Decodes to @'Last' 'Nothing'@ when the key is not present.
  
  @since 1.2.1.0
  -}
  last :: (Key -> TomlCodec a) -> Key -> TomlCodec (Last a)
  last codec = diwrap . dioptional . codec
  {-# INLINE last #-}
  