    {-# OPTIONS_GHC -fno-warn-orphans #-}
    {-# LANGUAGE CPP                        #-}
    {-# LANGUAGE FlexibleContexts           #-}
    {-# LANGUAGE FlexibleInstances          #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    {-# LANGUAGE MultiParamTypeClasses      #-}
    {-# LANGUAGE TemplateHaskell            #-}
    {-# LANGUAGE TupleSections              #-}
    module Text.Mustache.Internal.Types
      ( Array
      , ASTree
      , Context (..)
      , DataIdentifier (..)
      , Key
      , Node (..)
      , Object
      , Pair
      , STree
      , SubM (..)
      , SubstitutionError (..)
      , Template (..)
      , TemplateCache
      , ToMustache (..)
      , Value (..)
      , innerSearch
      , integralToMustache
      , runSubM
      , search
      , shiftContext
      , tellError
      , tellSuccess
      ) where

    import           Control.Arrow ( Arrow (..) )
    import           Control.Monad.RWS
                       ( MonadReader (..), MonadWriter (..), RWS, RWST (..), asks
                       , evalRWS
                       )
    import qualified Data.Aeson as Aeson
    #if MIN_VERSION_aeson(2,0,0)
    import qualified Data.Aeson.KeyMap as KM
    #endif
    import           Data.Foldable ( toList )
    import qualified Data.HashMap.Strict as HM
    import qualified Data.HashSet as HS
    import           Data.Int ( Int8, Int16, Int32, Int64 )
    import qualified Data.Map as Map
    import           Data.Scientific ( Scientific, fromFloatDigits )
    import qualified Data.Sequence as Seq
    import qualified Data.Set as Set
    import           Data.Text ( Text )
    import qualified Data.Text as T
    import qualified Data.Text.Lazy as LT
    import qualified Data.Vector as V
    import           Data.Word ( Word8, Word16, Word32, Word64 )
    import           Language.Haskell.TH.Lift (deriveLift)
    #if !MIN_VERSION_unordered_containers(0,2,17) || !MIN_VERSION_text(1,2,4)
    import           Language.Haskell.TH.Syntax ( Lift (..) )
    #endif
    import           Numeric.Natural ( Natural )

    -- | Type of errors we may encounter during substitution.

    data SubstitutionError
      = VariableNotFound [Key]
        -- ^ The template contained a variable for which there was no data

        -- counterpart in the current context

      | InvalidImplicitSectionContextType String
        -- ^ When substituting an implicit section the current context had an

        -- unsubstitutable type

      | InvertedImplicitSection
        -- ^ Inverted implicit sections should never occur

      | SectionTargetNotFound [Key]
        -- ^ The template contained a section for which there was no data

        -- counterpart in the current context

      | PartialNotFound FilePath
        -- ^ The template contained a partial for which there was no data

        -- counterpart in the current context

      | DirectlyRenderedValue Value
        -- ^ A complex value such as an Object or Array was directly rendered into

        -- the template (warning)

      deriving (Int -> SubstitutionError -> ShowS
    [SubstitutionError] -> ShowS
    SubstitutionError -> String
    (Int -> SubstitutionError -> ShowS)
    -> (SubstitutionError -> String)
    -> ([SubstitutionError] -> ShowS)
    -> Show SubstitutionError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> SubstitutionError -> ShowS
    showsPrec :: Int -> SubstitutionError -> ShowS
    $cshow :: SubstitutionError -> String
    show :: SubstitutionError -> String
    $cshowList :: [SubstitutionError] -> ShowS
    showList :: [SubstitutionError] -> ShowS
    Show)

    tellError :: SubstitutionError -> SubM ()
    tellError :: SubstitutionError -> SubM ()
    tellError SubstitutionError
    e = RWS
      (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
    -> SubM ()
    forall a.
    RWS
      (Context Value, TemplateCache) ([SubstitutionError], [Key]) () a
    -> SubM a
    SubM (RWS
       (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
     -> SubM ())
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
    -> SubM ()
    forall a b. (a -> b) -> a -> b
    $ ([SubstitutionError], [Key])
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
    tell ([SubstitutionError
    e], [])

    tellSuccess :: Text -> SubM ()
    tellSuccess :: Key -> SubM ()
    tellSuccess Key
    s = RWS
      (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
    -> SubM ()
    forall a.
    RWS
      (Context Value, TemplateCache) ([SubstitutionError], [Key]) () a
    -> SubM a
    SubM (RWS
       (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
     -> SubM ())
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
    -> SubM ()
    forall a b. (a -> b) -> a -> b
    $ ([SubstitutionError], [Key])
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () ()
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
    tell ([], [Key
    s])

    newtype SubM a = SubM
      { forall a.
    SubM a
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () a
    runSubM' :: RWS (Context Value, TemplateCache) ([SubstitutionError], [Text]) () a
      }
      deriving (Applicative SubM
    Applicative SubM =>
    (forall a b. SubM a -> (a -> SubM b) -> SubM b)
    -> (forall a b. SubM a -> SubM b -> SubM b)
    -> (forall a. a -> SubM a)
    -> Monad SubM
    forall a. a -> SubM a
    forall a b. SubM a -> SubM b -> SubM b
    forall a b. SubM a -> (a -> SubM b) -> SubM b
    forall (m :: * -> *).
    Applicative m =>
    (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall a b. SubM a -> (a -> SubM b) -> SubM b
    >>= :: forall a b. SubM a -> (a -> SubM b) -> SubM b
    $c>> :: forall a b. SubM a -> SubM b -> SubM b
    >> :: forall a b. SubM a -> SubM b -> SubM b
    $creturn :: forall a. a -> SubM a
    return :: forall a. a -> SubM a
    Monad, (forall a b. (a -> b) -> SubM a -> SubM b)
    -> (forall a b. a -> SubM b -> SubM a) -> Functor SubM
    forall a b. a -> SubM b -> SubM a
    forall a b. (a -> b) -> SubM a -> SubM b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> SubM a -> SubM b
    fmap :: forall a b. (a -> b) -> SubM a -> SubM b
    $c<$ :: forall a b. a -> SubM b -> SubM a
    <$ :: forall a b. a -> SubM b -> SubM a
    Functor, Functor SubM
    Functor SubM =>
    (forall a. a -> SubM a)
    -> (forall a b. SubM (a -> b) -> SubM a -> SubM b)
    -> (forall a b c. (a -> b -> c) -> SubM a -> SubM b -> SubM c)
    -> (forall a b. SubM a -> SubM b -> SubM b)
    -> (forall a b. SubM a -> SubM b -> SubM a)
    -> Applicative SubM
    forall a. a -> SubM a
    forall a b. SubM a -> SubM b -> SubM a
    forall a b. SubM a -> SubM b -> SubM b
    forall a b. SubM (a -> b) -> SubM a -> SubM b
    forall a b c. (a -> b -> c) -> SubM a -> SubM b -> SubM c
    forall (f :: * -> *).
    Functor f =>
    (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    $cpure :: forall a. a -> SubM a
    pure :: forall a. a -> SubM a
    $c<*> :: forall a b. SubM (a -> b) -> SubM a -> SubM b
    <*> :: forall a b. SubM (a -> b) -> SubM a -> SubM b
    $cliftA2 :: forall a b c. (a -> b -> c) -> SubM a -> SubM b -> SubM c
    liftA2 :: forall a b c. (a -> b -> c) -> SubM a -> SubM b -> SubM c
    $c*> :: forall a b. SubM a -> SubM b -> SubM b
    *> :: forall a b. SubM a -> SubM b -> SubM b
    $c<* :: forall a b. SubM a -> SubM b -> SubM a
    <* :: forall a b. SubM a -> SubM b -> SubM a
    Applicative, MonadReader (Context Value, TemplateCache))

    runSubM :: SubM a -> Context Value -> TemplateCache -> ([SubstitutionError], [Text])
    runSubM :: forall a.
    SubM a
    -> Context Value -> TemplateCache -> ([SubstitutionError], [Key])
    runSubM SubM a
    comp Context Value
    ctx TemplateCache
    cache = (a, ([SubstitutionError], [Key])) -> ([SubstitutionError], [Key])
    forall a b. (a, b) -> b
    snd ((a, ([SubstitutionError], [Key])) -> ([SubstitutionError], [Key]))
    -> (a, ([SubstitutionError], [Key]))
    -> ([SubstitutionError], [Key])
    forall a b. (a -> b) -> a -> b
    $ RWS
      (Context Value, TemplateCache) ([SubstitutionError], [Key]) () a
    -> (Context Value, TemplateCache)
    -> ()
    -> (a, ([SubstitutionError], [Key]))
    forall r w s a. RWS r w s a -> r -> s -> (a, w)
    evalRWS (SubM a
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () a
    forall a.
    SubM a
    -> RWS
         (Context Value, TemplateCache) ([SubstitutionError], [Key]) () a
    runSubM' SubM a
    comp) (Context Value
    ctx, TemplateCache
    cache) ()

    shiftContext :: Context Value -> SubM a -> SubM a
    shiftContext :: forall a. Context Value -> SubM a -> SubM a
    shiftContext = ((Context Value, TemplateCache) -> (Context Value, TemplateCache))
    -> SubM a -> SubM a
    forall a.
    ((Context Value, TemplateCache) -> (Context Value, TemplateCache))
    -> SubM a -> SubM a
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (((Context Value, TemplateCache) -> (Context Value, TemplateCache))
     -> SubM a -> SubM a)
    -> (Context Value
        -> (Context Value, TemplateCache)
        -> (Context Value, TemplateCache))
    -> Context Value
    -> SubM a
    -> SubM a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Context Value -> Context Value)
    -> (Context Value, TemplateCache) -> (Context Value, TemplateCache)
    forall b c d. (b -> c) -> (b, d) -> (c, d)
    forall (a :: * -> * -> *) b c d.
    Arrow a =>
    a b c -> a (b, d) (c, d)
    first ((Context Value -> Context Value)
     -> (Context Value, TemplateCache)
     -> (Context Value, TemplateCache))
    -> (Context Value -> Context Value -> Context Value)
    -> Context Value
    -> (Context Value, TemplateCache)
    -> (Context Value, TemplateCache)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Context Value -> Context Value -> Context Value
    forall a b. a -> b -> a
    const

    -- | Search for a key in the current context.

    --

    -- The search is conducted inside out mening the current focus

    -- is searched first. If the key is not found the outer scopes are recursively

    -- searched until the key is found, then 'innerSearch' is called on the result.

    search :: [Key] -> SubM (Maybe Value)
    search :: [Key] -> SubM (Maybe Value)
    search [] = Maybe Value -> SubM (Maybe Value)
    forall a. a -> SubM a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe Value
    forall a. Maybe a
    Nothing
    search (Key
    key:[Key]
    nextKeys) = (Maybe Value -> (Value -> Maybe Value) -> Maybe Value
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= [Key] -> Value -> Maybe Value
    innerSearch [Key]
    nextKeys) (Maybe Value -> Maybe Value)
    -> SubM (Maybe Value) -> SubM (Maybe Value)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> SubM (Maybe Value)
    go
      where
        go :: SubM (Maybe Value)
    go = ((Context Value, TemplateCache) -> Context Value)
    -> SubM (Context Value)
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks (Context Value, TemplateCache) -> Context Value
    forall a b. (a, b) -> a
    fst SubM (Context Value)
    -> (Context Value -> SubM (Maybe Value)) -> SubM (Maybe Value)
    forall a b. SubM a -> (a -> SubM b) -> SubM b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
          Context [Value]
    parents Value
    focus -> do
            let searchParents :: SubM (Maybe Value)
    searchParents = case [Value]
    parents of
                  (Value
    newFocus: [Value]
    newParents) -> Context Value -> SubM (Maybe Value) -> SubM (Maybe Value)
    forall a. Context Value -> SubM a -> SubM a
    shiftContext ([Value] -> Value -> Context Value
    forall α. [α] -> α -> Context α
    Context [Value]
    newParents Value
    newFocus) SubM (Maybe Value)
    go
                  [Value]
    _ -> Maybe Value -> SubM (Maybe Value)
    forall a. a -> SubM a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Maybe Value
    forall a. Maybe a
    Nothing
            case Value
    focus of
              Object Object
    o ->
                case Key -> Object -> Maybe Value
    forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
    HM.lookup Key
    key Object
    o of
                  Just Value
    res -> Maybe Value -> SubM (Maybe Value)
    forall a. a -> SubM a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe Value -> SubM (Maybe Value))
    -> Maybe Value -> SubM (Maybe Value)
    forall a b. (a -> b) -> a -> b
    $ Value -> Maybe Value
    forall a. a -> Maybe a
    Just Value
    res
                  Maybe Value
    _ -> SubM (Maybe Value)
    searchParents
              Value
    _ -> SubM (Maybe Value)
    searchParents

    -- | Searches nested scopes navigating inward. Fails if it encunters something

    -- other than an object before the key is expended.

    innerSearch :: [Key] -> Value -> Maybe Value
    innerSearch :: [Key] -> Value -> Maybe Value
    innerSearch []     Value
    v          = Value -> Maybe Value
    forall a. a -> Maybe a
    Just Value
    v
    innerSearch (Key
    y:[Key]
    ys) (Object Object
    o) = Key -> Object -> Maybe Value
    forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
    HM.lookup Key
    y Object
    o Maybe Value -> (Value -> Maybe Value) -> Maybe Value
    forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= [Key] -> Value -> Maybe Value
    innerSearch [Key]
    ys
    innerSearch [Key]
    _      Value
    _          = Maybe Value
    forall a. Maybe a
    Nothing

    -- | Syntax tree for a mustache template

    type STree = ASTree Text

    type ASTree α = [Node α]

    -- | Basic values composing the STree

    data Node α
      = TextBlock α
      | Section DataIdentifier (ASTree α)
      | InvertedSection DataIdentifier (ASTree α)
      | Variable Bool DataIdentifier
      | Partial (Maybe α) FilePath
      deriving (Int -> Node α -> ShowS
    [Node α] -> ShowS
    Node α -> String
    (Int -> Node α -> ShowS)
    -> (Node α -> String) -> ([Node α] -> ShowS) -> Show (Node α)
    forall α. Show α => Int -> Node α -> ShowS
    forall α. Show α => [Node α] -> ShowS
    forall α. Show α => Node α -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall α. Show α => Int -> Node α -> ShowS
    showsPrec :: Int -> Node α -> ShowS
    $cshow :: forall α. Show α => Node α -> String
    show :: Node α -> String
    $cshowList :: forall α. Show α => [Node α] -> ShowS
    showList :: [Node α] -> ShowS
    Show, Node α -> Node α -> Bool
    (Node α -> Node α -> Bool)
    -> (Node α -> Node α -> Bool) -> Eq (Node α)
    forall α. Eq α => Node α -> Node α -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall α. Eq α => Node α -> Node α -> Bool
    == :: Node α -> Node α -> Bool
    $c/= :: forall α. Eq α => Node α -> Node α -> Bool
    /= :: Node α -> Node α -> Bool
    Eq)

    -- | Kinds of identifiers for Variables and sections

    data DataIdentifier
      = NamedData [Key]
      | Implicit
      deriving (Int -> DataIdentifier -> ShowS
    [DataIdentifier] -> ShowS
    DataIdentifier -> String
    (Int -> DataIdentifier -> ShowS)
    -> (DataIdentifier -> String)
    -> ([DataIdentifier] -> ShowS)
    -> Show DataIdentifier
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> DataIdentifier -> ShowS
    showsPrec :: Int -> DataIdentifier -> ShowS
    $cshow :: DataIdentifier -> String
    show :: DataIdentifier -> String
    $cshowList :: [DataIdentifier] -> ShowS
    showList :: [DataIdentifier] -> ShowS
    Show, DataIdentifier -> DataIdentifier -> Bool
    (DataIdentifier -> DataIdentifier -> Bool)
    -> (DataIdentifier -> DataIdentifier -> Bool) -> Eq DataIdentifier
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: DataIdentifier -> DataIdentifier -> Bool
    == :: DataIdentifier -> DataIdentifier -> Bool
    $c/= :: DataIdentifier -> DataIdentifier -> Bool
    /= :: DataIdentifier -> DataIdentifier -> Bool
    Eq)

    -- | A list-like structure used in 'Value'

    type Array  = V.Vector Value
    -- | A map-like structure used in 'Value'

    type Object = HM.HashMap Text Value
    -- | Source type for constructing 'Object's

    type Pair   = (Text, Value)

    -- | Representation of stateful context for the substitution process

    data Context α = Context { forall α. Context α -> [α]
    ctxtParents :: [α], forall α. Context α -> α
    ctxtFocus :: α }
      deriving (Context α -> Context α -> Bool
    (Context α -> Context α -> Bool)
    -> (Context α -> Context α -> Bool) -> Eq (Context α)
    forall α. Eq α => Context α -> Context α -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall α. Eq α => Context α -> Context α -> Bool
    == :: Context α -> Context α -> Bool
    $c/= :: forall α. Eq α => Context α -> Context α -> Bool
    /= :: Context α -> Context α -> Bool
    Eq, Int -> Context α -> ShowS
    [Context α] -> ShowS
    Context α -> String
    (Int -> Context α -> ShowS)
    -> (Context α -> String)
    -> ([Context α] -> ShowS)
    -> Show (Context α)
    forall α. Show α => Int -> Context α -> ShowS
    forall α. Show α => [Context α] -> ShowS
    forall α. Show α => Context α -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall α. Show α => Int -> Context α -> ShowS
    showsPrec :: Int -> Context α -> ShowS
    $cshow :: forall α. Show α => Context α -> String
    show :: Context α -> String
    $cshowList :: forall α. Show α => [Context α] -> ShowS
    showList :: [Context α] -> ShowS
    Show, Eq (Context α)
    Eq (Context α) =>
    (Context α -> Context α -> Ordering)
    -> (Context α -> Context α -> Bool)
    -> (Context α -> Context α -> Bool)
    -> (Context α -> Context α -> Bool)
    -> (Context α -> Context α -> Bool)
    -> (Context α -> Context α -> Context α)
    -> (Context α -> Context α -> Context α)
    -> Ord (Context α)
    Context α -> Context α -> Bool
    Context α -> Context α -> Ordering
    Context α -> Context α -> Context α
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall α. Ord α => Eq (Context α)
    forall α. Ord α => Context α -> Context α -> Bool
    forall α. Ord α => Context α -> Context α -> Ordering
    forall α. Ord α => Context α -> Context α -> Context α
    $ccompare :: forall α. Ord α => Context α -> Context α -> Ordering
    compare :: Context α -> Context α -> Ordering
    $c< :: forall α. Ord α => Context α -> Context α -> Bool
    < :: Context α -> Context α -> Bool
    $c<= :: forall α. Ord α => Context α -> Context α -> Bool
    <= :: Context α -> Context α -> Bool
    $c> :: forall α. Ord α => Context α -> Context α -> Bool
    > :: Context α -> Context α -> Bool
    $c>= :: forall α. Ord α => Context α -> Context α -> Bool
    >= :: Context α -> Context α -> Bool
    $cmax :: forall α. Ord α => Context α -> Context α -> Context α
    max :: Context α -> Context α -> Context α
    $cmin :: forall α. Ord α => Context α -> Context α -> Context α
    min :: Context α -> Context α -> Context α
    Ord)

    -- | Internal value representation

    data Value
      = Object !Object
      | Array  !Array
      | Number !Scientific
      | String !Text
      | Lambda (STree -> SubM STree)
      | Bool   !Bool
      | Null

    instance Show Value where
      show :: Value -> String
    show (Lambda STree -> SubM STree
    _) = String
    "Lambda function"
      show (Object Object
    o) = Object -> String
    forall a. Show a => a -> String
    show Object
    o
      show (Array  Array
    a) = Array -> String
    forall a. Show a => a -> String
    show Array
    a
      show (String Key
    s) = Key -> String
    forall a. Show a => a -> String
    show Key
    s
      show (Number Scientific
    n) = Scientific -> String
    forall a. Show a => a -> String
    show Scientific
    n
      show (Bool   Bool
    b) = Bool -> String
    forall a. Show a => a -> String
    show Bool
    b
      show Value
    Null       = String
    "null"

    listToMustache' :: ToMustache ω => [ω] -> Value
    listToMustache' :: forall ω. ToMustache ω => [ω] -> Value
    listToMustache' = Array -> Value
    Array (Array -> Value) -> ([ω] -> Array) -> [ω] -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Value] -> Array
    forall a. [a] -> Vector a
    V.fromList ([Value] -> Array) -> ([ω] -> [Value]) -> [ω] -> Array
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ω -> Value) -> [ω] -> [Value]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ω -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache

    integralToMustache :: Integral ω => ω -> Value
    integralToMustache :: forall ω. Integral ω => ω -> Value
    integralToMustache = Integer -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache (Integer -> Value) -> (ω -> Integer) -> ω -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ω -> Integer
    forall a. Integral a => a -> Integer
    toInteger

    -- | Conversion class

    class ToMustache ω where
      toMustache :: ω -> Value
      listToMustache :: [ω] -> Value
      listToMustache = [ω] -> Value
    forall ω. ToMustache ω => [ω] -> Value
    listToMustache'

    instance ToMustache Float where
      toMustache :: Float -> Value
    toMustache = Scientific -> Value
    Number (Scientific -> Value) -> (Float -> Scientific) -> Float -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Float -> Scientific
    forall a. RealFloat a => a -> Scientific
    fromFloatDigits

    instance ToMustache Double where
      toMustache :: Double -> Value
    toMustache = Scientific -> Value
    Number (Scientific -> Value) -> (Double -> Scientific) -> Double -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Scientific
    forall a. RealFloat a => a -> Scientific
    fromFloatDigits

    instance ToMustache Integer where
      toMustache :: Integer -> Value
    toMustache = Scientific -> Value
    Number (Scientific -> Value)
    -> (Integer -> Scientific) -> Integer -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Scientific
    forall a. Num a => Integer -> a
    fromInteger

    instance ToMustache Natural where
      toMustache :: Natural -> Value
    toMustache = Natural -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Int where
      toMustache :: Int -> Value
    toMustache = Int -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Word where
      toMustache :: Word -> Value
    toMustache = Word -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Int8 where
      toMustache :: Int8 -> Value
    toMustache = Int8 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Int16 where
      toMustache :: Int16 -> Value
    toMustache = Int16 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Int32 where
      toMustache :: Int32 -> Value
    toMustache = Int32 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Int64 where
      toMustache :: Int64 -> Value
    toMustache = Int64 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Word8 where
      toMustache :: Word8 -> Value
    toMustache = Word8 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Word16 where
      toMustache :: Word16 -> Value
    toMustache = Word16 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Word32 where
      toMustache :: Word32 -> Value
    toMustache = Word32 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Word64 where
      toMustache :: Word64 -> Value
    toMustache = Word64 -> Value
    forall ω. Integral ω => ω -> Value
    integralToMustache

    instance ToMustache Char where
      toMustache :: Char -> Value
    toMustache = String -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache (String -> Value) -> (Char -> String) -> Char -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> ShowS
    forall a. a -> [a] -> [a]
    :[])
      listToMustache :: String -> Value
    listToMustache = Key -> Value
    String (Key -> Value) -> (String -> Key) -> String -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Key
    T.pack

    instance ToMustache Value where
      toMustache :: Value -> Value
    toMustache = Value -> Value
    forall a. a -> a
    id

    instance ToMustache Bool where
      toMustache :: Bool -> Value
    toMustache = Bool -> Value
    Bool

    instance ToMustache () where
      toMustache :: () -> Value
    toMustache = Value -> () -> Value
    forall a b. a -> b -> a
    const Value
    Null

    instance ToMustache ω => ToMustache (Maybe ω) where
      toMustache :: Maybe ω -> Value
    toMustache (Just ω
    w) = ω -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ω
    w
      toMustache Maybe ω
    Nothing  = Value
    Null

    instance ToMustache Text where
      toMustache :: Key -> Value
    toMustache = Key -> Value
    String

    instance ToMustache LT.Text where
      toMustache :: Text -> Value
    toMustache = Key -> Value
    String (Key -> Value) -> (Text -> Key) -> Text -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Key
    LT.toStrict

    instance ToMustache Scientific where
      toMustache :: Scientific -> Value
    toMustache = Scientific -> Value
    Number

    instance ToMustache α => ToMustache [α] where
      toMustache :: [α] -> Value
    toMustache = [α] -> Value
    forall ω. ToMustache ω => [ω] -> Value
    listToMustache

    instance ToMustache ω => ToMustache (Seq.Seq ω) where
      toMustache :: Seq ω -> Value
    toMustache = [ω] -> Value
    forall ω. ToMustache ω => [ω] -> Value
    listToMustache' ([ω] -> Value) -> (Seq ω -> [ω]) -> Seq ω -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Seq ω -> [ω]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList

    instance ToMustache ω => ToMustache (V.Vector ω) where
      toMustache :: Vector ω -> Value
    toMustache = Array -> Value
    Array (Array -> Value) -> (Vector ω -> Array) -> Vector ω -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ω -> Value) -> Vector ω -> Array
    forall a b. (a -> b) -> Vector a -> Vector b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ω -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache

    instance (ToMustache ω) => ToMustache (Map.Map Text ω) where
      toMustache :: Map Key ω -> Value
    toMustache = (Key -> Key) -> Map Key ω -> Value
    forall v a. ToMustache v => (a -> Key) -> Map a v -> Value
    mapInstanceHelper Key -> Key
    forall a. a -> a
    id

    instance (ToMustache ω) => ToMustache (Map.Map LT.Text ω) where
      toMustache :: Map Text ω -> Value
    toMustache = (Text -> Key) -> Map Text ω -> Value
    forall v a. ToMustache v => (a -> Key) -> Map a v -> Value
    mapInstanceHelper Text -> Key
    LT.toStrict

    instance (ToMustache ω) => ToMustache (Map.Map String ω) where
      toMustache :: Map String ω -> Value
    toMustache = (String -> Key) -> Map String ω -> Value
    forall v a. ToMustache v => (a -> Key) -> Map a v -> Value
    mapInstanceHelper String -> Key
    T.pack

    mapInstanceHelper :: ToMustache v => (a -> Text) -> Map.Map a v -> Value
    mapInstanceHelper :: forall v a. ToMustache v => (a -> Key) -> Map a v -> Value
    mapInstanceHelper a -> Key
    conv =
      Object -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
      (Object -> Value) -> (Map a v -> Object) -> Map a v -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> v -> Object -> Object) -> Object -> Map a v -> Object
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey
        (\a
    k -> Key -> Value -> Object -> Object
    forall k v.
    (Eq k, Hashable k) =>
    k -> v -> HashMap k v -> HashMap k v
    HM.insert (a -> Key
    conv a
    k) (Value -> Object -> Object)
    -> (v -> Value) -> v -> Object -> Object
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache)
        Object
    forall k v. HashMap k v
    HM.empty

    instance ToMustache ω => ToMustache (HM.HashMap Text ω) where
      toMustache :: HashMap Key ω -> Value
    toMustache = Object -> Value
    Object (Object -> Value)
    -> (HashMap Key ω -> Object) -> HashMap Key ω -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ω -> Value) -> HashMap Key ω -> Object
    forall a b. (a -> b) -> HashMap Key a -> HashMap Key b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ω -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache

    instance ToMustache ω => ToMustache (HM.HashMap LT.Text ω) where
      toMustache :: HashMap Text ω -> Value
    toMustache = (Text -> Key) -> HashMap Text ω -> Value
    forall v a. ToMustache v => (a -> Key) -> HashMap a v -> Value
    hashMapInstanceHelper Text -> Key
    LT.toStrict

    instance ToMustache ω => ToMustache (HM.HashMap String ω) where
      toMustache :: HashMap String ω -> Value
    toMustache = (String -> Key) -> HashMap String ω -> Value
    forall v a. ToMustache v => (a -> Key) -> HashMap a v -> Value
    hashMapInstanceHelper String -> Key
    T.pack

    hashMapInstanceHelper :: ToMustache v => (a -> Text) -> HM.HashMap a v -> Value
    hashMapInstanceHelper :: forall v a. ToMustache v => (a -> Key) -> HashMap a v -> Value
    hashMapInstanceHelper a -> Key
    conv =
      Object -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
      (Object -> Value)
    -> (HashMap a v -> Object) -> HashMap a v -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> v -> Object -> Object) -> Object -> HashMap a v -> Object
    forall k v a. (k -> v -> a -> a) -> a -> HashMap k v -> a
    HM.foldrWithKey
        (\a
    k -> Key -> Value -> Object -> Object
    forall k v.
    (Eq k, Hashable k) =>
    k -> v -> HashMap k v -> HashMap k v
    HM.insert (a -> Key
    conv a
    k) (Value -> Object -> Object)
    -> (v -> Value) -> v -> Object -> Object
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . v -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache)
        Object
    forall k v. HashMap k v
    HM.empty

    instance ToMustache (STree -> SubM STree) where
        toMustache :: (STree -> SubM STree) -> Value
    toMustache = (STree -> SubM STree) -> Value
    Lambda

    instance ToMustache Aeson.Value where
      toMustache :: Value -> Value
    toMustache (Aeson.Object Object
    o) = Object -> Value
    Object (Object -> Value) -> Object -> Value
    forall a b. (a -> b) -> a -> b
    $ (Value -> Value) -> HashMap Key Value -> Object
    forall a b. (a -> b) -> HashMap Key a -> HashMap Key b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Value -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
    #if MIN_VERSION_aeson(2,0,0)
        (Object -> HashMap Key Value
    forall v. KeyMap v -> HashMap Key v
    KM.toHashMapText Object
    o)
    #else
        o
    #endif
      toMustache (Aeson.Array  Array
    a) = Array -> Value
    Array (Array -> Value) -> Array -> Value
    forall a b. (a -> b) -> a -> b
    $ (Value -> Value) -> Array -> Array
    forall a b. (a -> b) -> Vector a -> Vector b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Value -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache Array
    a
      toMustache (Aeson.Number Scientific
    n) = Scientific -> Value
    Number Scientific
    n
      toMustache (Aeson.String Key
    s) = Key -> Value
    String Key
    s
      toMustache (Aeson.Bool   Bool
    b) = Bool -> Value
    Bool Bool
    b
      toMustache Value
    Aeson.Null       = Value
    Null

    instance ToMustache ω => ToMustache (HS.HashSet ω) where
      toMustache :: HashSet ω -> Value
    toMustache = [ω] -> Value
    forall ω. ToMustache ω => [ω] -> Value
    listToMustache' ([ω] -> Value) -> (HashSet ω -> [ω]) -> HashSet ω -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HashSet ω -> [ω]
    forall a. HashSet a -> [a]
    HS.toList

    instance ToMustache ω => ToMustache (Set.Set ω) where
      toMustache :: Set ω -> Value
    toMustache = [ω] -> Value
    forall ω. ToMustache ω => [ω] -> Value
    listToMustache' ([ω] -> Value) -> (Set ω -> [ω]) -> Set ω -> Value
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Set ω -> [ω]
    forall a. Set a -> [a]
    Set.toList

    instance (ToMustache α, ToMustache β) => ToMustache (α, β) where
      toMustache :: (α, β) -> Value
    toMustache (α
    a, β
    b) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache [α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a, β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b]

    instance (ToMustache α, ToMustache β, ToMustache γ)
             => ToMustache (α, β, γ) where
      toMustache :: (α, β, γ) -> Value
    toMustache (α
    a, β
    b, γ
    c) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache [α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a, β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b, γ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache γ
    c]

    instance (ToMustache α, ToMustache β, ToMustache γ, ToMustache δ)
             => ToMustache (α, β, γ, δ) where
      toMustache :: (α, β, γ, δ) -> Value
    toMustache (α
    a, β
    b, γ
    c, δ
    d) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
        [ α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a
        , β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b
        , γ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache γ
    c
        , δ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache δ
    d
        ]

    instance ( ToMustache α
             , ToMustache β
             , ToMustache γ
             , ToMustache δ
             , ToMustache ε
             ) => ToMustache (α, β, γ, δ, ε) where
      toMustache :: (α, β, γ, δ, ε) -> Value
    toMustache (α
    a, β
    b, γ
    c, δ
    d, ε
    e) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
        [ α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a
        , β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b
        , γ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache γ
    c
        , δ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache δ
    d
        , ε -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ε
    e
        ]

    instance ( ToMustache α
             , ToMustache β
             , ToMustache γ
             , ToMustache δ
             , ToMustache ε
             , ToMustache ζ
             ) => ToMustache (α, β, γ, δ, ε, ζ) where
      toMustache :: (α, β, γ, δ, ε, ζ) -> Value
    toMustache (α
    a, β
    b, γ
    c, δ
    d, ε
    e, ζ
    f) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
        [ α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a
        , β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b
        , γ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache γ
    c
        , δ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache δ
    d
        , ε -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ε
    e
        , ζ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ζ
    f
        ]

    instance ( ToMustache α
             , ToMustache β
             , ToMustache γ
             , ToMustache δ
             , ToMustache ε
             , ToMustache ζ
             , ToMustache η
             ) => ToMustache (α, β, γ, δ, ε, ζ, η) where
      toMustache :: (α, β, γ, δ, ε, ζ, η) -> Value
    toMustache (α
    a, β
    b, γ
    c, δ
    d, ε
    e, ζ
    f, η
    g) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
        [ α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a
        , β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b
        , γ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache γ
    c
        , δ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache δ
    d
        , ε -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ε
    e
        , ζ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ζ
    f
        , η -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache η
    g
        ]

    instance ( ToMustache α
             , ToMustache β
             , ToMustache γ
             , ToMustache δ
             , ToMustache ε
             , ToMustache ζ
             , ToMustache η
             , ToMustache θ
             ) => ToMustache (α, β, γ, δ, ε, ζ, η, θ) where
      toMustache :: (α, β, γ, δ, ε, ζ, η, θ) -> Value
    toMustache (α
    a, β
    b, γ
    c, δ
    d, ε
    e, ζ
    f, η
    g, θ
    h) = [Value] -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache
        [ α -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache α
    a
        , β -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache β
    b
        , γ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache γ
    c
        , δ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache δ
    d
        , ε -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ε
    e
        , ζ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache ζ
    f
        , η -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache η
    g
        , θ -> Value
    forall ω. ToMustache ω => ω -> Value
    toMustache θ
    h
        ]

    -- | A collection of templates with quick access via their hashed names

    type TemplateCache = HM.HashMap String Template

    -- | Type of key used for retrieving data from 'Value's

    type Key = Text

    {-|
      A compiled Template with metadata.
    -}
    data Template = Template
      { Template -> String
    name     :: String
      , Template -> STree
    ast      :: STree
      , Template -> TemplateCache
    partials :: TemplateCache
      } deriving (Int -> Template -> ShowS
    [Template] -> ShowS
    Template -> String
    (Int -> Template -> ShowS)
    -> (Template -> String) -> ([Template] -> ShowS) -> Show Template
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Template -> ShowS
    showsPrec :: Int -> Template -> ShowS
    $cshow :: Template -> String
    show :: Template -> String
    $cshowList :: [Template] -> ShowS
    showList :: [Template] -> ShowS
    Show)

    deriveLift ''DataIdentifier
    deriveLift ''Node
    deriveLift ''Template

    -- Data.HashMap 0.2.17.0 introduces its own Lift instance

    #if !MIN_VERSION_unordered_containers(0,2,17)
    instance Lift TemplateCache where
    #if MIN_VERSION_template_haskell(2,16,0)
      liftTyped m = [|| HM.fromList $$(liftTyped $ HM.toList m) ||]
    #else
      lift m = [| HM.fromList $(lift $ HM.toList m) |]
    #endif
    #endif

    --Data.Text 1.2.4.0 introduces its own Lift Text instance

    #if !MIN_VERSION_text(1,2,4)
    instance Lift Text where
      lift = lift . T.unpack
    #endif