content: {-|
  Module      : $Header$
  Description : Types and conversions
  Copyright   : (c) Justus Adam, 2015
  License     : BSD3
  Maintainer  : dev@justus.science
  Stability   : experimental
  Portability : POSIX
  -}
  module Text.Mustache.Types
    (
      -- * Types for the Parser / Template
      ASTree
    , STree
    , Node (..)
    , DataIdentifier (..)
    , Template (..)
    , TemplateCache
      -- * Types for the Substitution / Data
    , Value (..)
    , Key
      -- ** Converting
    , object
    , (~>)
    , (↝)
    , (~=)
    , (⥱)
    , ToMustache
    , toMustache
    , mFromJSON
    , integralToMustache
      -- ** Representation
    , Array
    , Object
    , Pair
    , SubM
    , askContext
    , askPartials
    , Context (..)
    ) where
  
  
  import           Control.Monad.Reader ( asks )
  import qualified Data.Aeson as Aeson
  import qualified Data.HashMap.Strict as HM
  import           Data.Text ( Text )
  import           Text.Mustache.Internal.Types
                     ( ASTree, Array, Context (..), DataIdentifier (..), Key
                     , Node (..), Object, Pair, STree, SubM, Template (..)
                     , TemplateCache, ToMustache (..), Value (..)
                     , integralToMustache
                     )
  
  
  -- | Convenience function for creating Object values.
  --
  -- This function is supposed to be used in conjuction with the '~>' and '~=' operators.
  --
  -- ==== __Examples__
  --
  -- @
  --   data Address = Address { ... }
  --
  --   instance Address ToJSON where
  --     ...
  --
  --   data Person = Person { name :: String, address :: Address }
  --
  --   instance ToMustache Person where
  --     toMustache (Person { name, address }) = object
  --       [ "name" ~> name
  --       , "address" ~= address
  --       ]
  -- @
  --
  -- Here we can see that we can use the '~>' operator for values that have
  -- themselves a 'ToMustache' instance, or alternatively if they lack such an
  -- instance but provide an instance for the 'ToJSON' typeclass we can use the
  -- '~=' operator.
  object :: [Pair] -> Value
  object = Object . HM.fromList
  
  
  -- | Map keys to values that provide a 'ToMustache' instance
  --
  -- Recommended in conjunction with the `OverloadedStrings` extension.
  (~>) :: ToMustache ω => Text -> ω -> Pair
  (~>) t = (t, ) . toMustache
  {-# INLINEABLE (~>) #-}
  infixr 8 ~>
  
  -- | Unicode version of '~>'
  (↝) :: ToMustache ω => Text -> ω -> Pair
  (↝) = (~>)
  {-# INLINEABLE (↝) #-}
  infixr 8 ↝
  
  
  -- | Map keys to values that provide a 'ToJSON' instance
  --
  -- Recommended in conjunction with the `OverloadedStrings` extension.
  (~=) :: Aeson.ToJSON ι => Text -> ι -> Pair
  (~=) t = (t ~>) . Aeson.toJSON
  {-# INLINEABLE (~=) #-}
  infixr 8 ~=
  
  
  -- | Unicode version of '~='
  (⥱) :: Aeson.ToJSON ι => Text -> ι -> Pair
  (⥱) = (~=)
  {-# INLINEABLE (⥱) #-}
  infixr 8 ⥱
  
  
  -- | Converts a value that can be represented as JSON to a Value.
  mFromJSON :: Aeson.ToJSON ι => ι -> Value
  mFromJSON = toMustache . Aeson.toJSON
  
  
  askContext :: SubM (Context Value)
  askContext = asks fst
  
  
  askPartials :: SubM TemplateCache
  askPartials = asks snd
  