module Text.Mustache.Types
(
AST
, Template(..)
, Node(..)
, DataIdentifier(..)
, Value(..)
, Key
, object
, (~>), (↝), (~=), (⥱), (~~>), (~↝), (~~=), (~⥱)
, ToMustache, toMustache, toTextBlock, mFromJSON
, Array, Object, Pair
, Context(..)
, TemplateCache
) where
import Conversion
import Conversion.Text ()
import qualified Data.Aeson as Aeson
import Data.HashMap.Strict as HM
import qualified Data.HashSet as HS
import qualified Data.Map as Map
import Data.Scientific
import Data.Text
import qualified Data.Text.Lazy as LT
import qualified Data.Vector as V
import Prelude.Unicode
type AST = [Node Text]
data Node α
= TextBlock α
| Section DataIdentifier AST
| InvertedSection DataIdentifier AST
| Variable Bool DataIdentifier
| Partial (Maybe α) FilePath
deriving (Show, Eq)
data DataIdentifier
= NamedData [Key]
| Implicit
deriving (Show, Eq)
type Array = V.Vector Value
type Object = HM.HashMap Text Value
type Pair = (Text, Value)
data Context α = Context [α] α
deriving (Eq, Show, Ord)
data Value
= Object Object
| Array Array
| Number Scientific
| String Text
| Lambda (Context Value → AST → AST)
| Bool Bool
| Null
instance Show Value where
show (Lambda _) = "Lambda function"
show (Object o) = show o
show (Array a) = show a
show (String s) = show s
show (Number n) = show n
show (Bool b) = show b
show Null = "null"
class ToMustache ω where
toMustache ∷ ω → Value
instance ToMustache Value where
toMustache = id
instance ToMustache [Char] where
toMustache = toMustache ∘ pack
instance ToMustache Bool where
toMustache = Bool
instance ToMustache Char where
toMustache = String ∘ pack ∘ return
instance ToMustache () where
toMustache = const Null
instance ToMustache Text where
toMustache = String
instance ToMustache LT.Text where
toMustache = String ∘ LT.toStrict
instance ToMustache Scientific where
toMustache = Number
instance ToMustache ω ⇒ ToMustache [ω] where
toMustache = Array ∘ V.fromList ∘ fmap toMustache
instance ToMustache (V.Vector Value) where
toMustache = Array
instance ToMustache ω ⇒ ToMustache (V.Vector ω) where
toMustache = toMustache ∘ fmap toMustache
instance ToMustache (HM.HashMap Text Value) where
toMustache = Object
instance (Conversion θ Text, ToMustache ω) ⇒ ToMustache (Map.Map θ ω) where
toMustache =
toMustache
∘ Map.foldrWithKey
(\k → HM.insert (convert k ∷ Text) ∘ toMustache)
HM.empty
instance ToMustache ω ⇒ ToMustache (HM.HashMap Text ω) where
toMustache = toMustache ∘ fmap toMustache
instance (Conversion θ Text, ToMustache ω) ⇒ ToMustache (HM.HashMap θ ω) where
toMustache =
toMustache
∘ HM.foldrWithKey
(\k → HM.insert (convert k ∷ Text) ∘ toMustache)
HM.empty
instance ToMustache (Context Value → AST → AST) where
toMustache = Lambda
instance ToMustache (Context Value → AST → Text) where
toMustache f = toMustache wrapper
where
wrapper ∷ Context Value → AST → AST
wrapper c lAST = return ∘ TextBlock $ f c lAST
instance Conversion θ Text
⇒ ToMustache (Context Value → AST → θ) where
toMustache f = toMustache wrapper
where
wrapper :: Context Value → AST → Text
wrapper c = convert ∘ f c
instance ToMustache (AST → AST) where
toMustache f = toMustache (const f ∷ Context Value → AST → AST)
instance ToMustache (AST → Text) where
toMustache f = toMustache wrapper
where
wrapper ∷ Context Value → AST → AST
wrapper _ = (return ∘ TextBlock) ∘ f
instance ToMustache Aeson.Value where
toMustache (Aeson.Object o) = Object $ fmap toMustache o
toMustache (Aeson.Array a) = Array $ fmap toMustache a
toMustache (Aeson.Number n) = Number n
toMustache (Aeson.String s) = String s
toMustache (Aeson.Bool b) = Bool b
toMustache Aeson.Null = Null
instance ToMustache ω ⇒ ToMustache (HS.HashSet ω) where
toMustache = toMustache ∘ HS.toList
instance (ToMustache α, ToMustache β) ⇒ ToMustache (α, β) where
toMustache (a, b) = toMustache [toMustache a, toMustache b]
instance (ToMustache α, ToMustache β, ToMustache γ)
⇒ ToMustache (α, β, γ) where
toMustache (a, b, c) = toMustache [toMustache a, toMustache b, toMustache c]
instance (ToMustache α, ToMustache β, ToMustache γ, ToMustache δ)
⇒ ToMustache (α, β, γ, δ) where
toMustache (a, b, c, d) = toMustache
[ toMustache a
, toMustache b
, toMustache c
, toMustache d
]
instance ( ToMustache α
, ToMustache β
, ToMustache γ
, ToMustache δ
, ToMustache ε
) ⇒ ToMustache (α, β, γ, δ, ε) where
toMustache (a, b, c, d, e) = toMustache
[ toMustache a
, toMustache b
, toMustache c
, toMustache d
, toMustache e
]
instance ( ToMustache α
, ToMustache β
, ToMustache γ
, ToMustache δ
, ToMustache ε
, ToMustache ζ
) ⇒ ToMustache (α, β, γ, δ, ε, ζ) where
toMustache (a, b, c, d, e, f) = toMustache
[ toMustache a
, toMustache b
, toMustache c
, toMustache d
, toMustache e
, toMustache f
]
instance ( ToMustache α
, ToMustache β
, ToMustache γ
, ToMustache δ
, ToMustache ε
, ToMustache ζ
, ToMustache η
) ⇒ ToMustache (α, β, γ, δ, ε, ζ, η) where
toMustache (a, b, c, d, e, f, g) = toMustache
[ toMustache a
, toMustache b
, toMustache c
, toMustache d
, toMustache e
, toMustache f
, toMustache g
]
instance ( ToMustache α
, ToMustache β
, ToMustache γ
, ToMustache δ
, ToMustache ε
, ToMustache ζ
, ToMustache η
, ToMustache θ
) ⇒ ToMustache (α, β, γ, δ, ε, ζ, η, θ) where
toMustache (a, b, c, d, e, f, g, h) = toMustache
[ toMustache a
, toMustache b
, toMustache c
, toMustache d
, toMustache e
, toMustache f
, toMustache g
, toMustache h
]
object ∷ [Pair] → Value
object = Object ∘ HM.fromList
(~>) ∷ ToMustache ω ⇒ Text → ω → Pair
(~>) t = (t, ) ∘ toMustache
infixr 8 ~>
(↝) ∷ ToMustache ω ⇒ Text → ω → Pair
(↝) = (~>)
infixr 8 ↝
(~=) ∷ Aeson.ToJSON ι ⇒ Text → ι → Pair
(~=) t = (t ~>) ∘ Aeson.toJSON
infixr 8 ~=
(⥱) ∷ Aeson.ToJSON ι ⇒ Text → ι → Pair
(⥱) = (~=)
infixr 8 ⥱
(~~>) ∷ (Conversion ζ Text, ToMustache ω) ⇒ ζ → ω → Pair
(~~>) = (~>) ∘ convert
infixr 8 ~~>
(~↝) ∷ (Conversion ζ Text, ToMustache ω) ⇒ ζ → ω → Pair
(~↝) = (~~>)
infixr 8 ~↝
(~~=) ∷ (Conversion ζ Text, Aeson.ToJSON ι) ⇒ ζ → ι → Pair
(~~=) = (~=) ∘ convert
infixr 8 ~~=
(~⥱) ∷ (Conversion ζ Text, Aeson.ToJSON ι) ⇒ ζ → ι → Pair
(~⥱) = (~~=)
infixr 8 ~⥱
toTextBlock ∷ Conversion ζ Text ⇒ ζ → Value
toTextBlock = String ∘ convert
mFromJSON ∷ Aeson.ToJSON ι ⇒ ι → Value
mFromJSON = toMustache ∘ Aeson.toJSON
type TemplateCache = HM.HashMap String Template
type Key = Text
data Template = Template
{ name ∷ String
, ast ∷ AST
, partials ∷ TemplateCache
} deriving (Show)