module Text.Mustache.Types
(
MustacheAST
, MustacheTemplate(..)
, MustacheNode(..)
, Value(..)
, object
, (~>), (~=), (~~>), (~~=)
, ToMustache, toMustache, toMustacheText, mFromJSON
, Array, Object
, Context(..)
) where
import qualified Data.Aeson as Aeson
import Data.Functor ((<$>))
import Data.HashMap.Strict as HM
import Data.Scientific
import Data.Text
import qualified Data.Text.Lazy as LT
import qualified Data.Vector as V
import Conversion
import Conversion.Text ()
type MustacheAST = [MustacheNode Text]
data MustacheNode a
= MustacheText a
| MustacheSection [Text] MustacheAST
| MustacheInvertedSection [Text] MustacheAST
| MustacheVariable Bool [Text]
| MustachePartial FilePath
deriving (Show, Eq)
type Array = V.Vector Value
type Object = HM.HashMap Text Value
type KeyValuePair = (Text, Value)
data Context a = Context [a] a
data Value
= Object Object
| Array Array
| Number Scientific
| String Text
| Lambda (Context Value → MustacheAST → Either String MustacheAST)
| Bool Bool
| Null
instance Show Value where
show (Lambda _) = "Lambda Context Value → MustacheAST → Either String MustacheAST"
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 a where
toMustache ∷ a → Value
instance ToMustache [Char] where
toMustache = String . 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 Value where
toMustache = id
instance ToMustache m ⇒ ToMustache [m] where
toMustache = Array . V.fromList . fmap toMustache
instance ToMustache m ⇒ ToMustache (V.Vector m) where
toMustache = Array . fmap toMustache
instance ToMustache m ⇒ ToMustache (HM.HashMap Text m) where
toMustache = Object . fmap toMustache
instance ToMustache (Context Value → MustacheAST → Either String MustacheAST) where
toMustache = Lambda
instance ToMustache (Context Value → MustacheAST → Either String Text) where
toMustache f = Lambda wrapper
where wrapper c lAST = return . MustacheText <$> f c lAST
instance ToMustache (Context Value → MustacheAST → MustacheAST) where
toMustache f = Lambda wrapper
where wrapper c = Right . f c
instance ToMustache (Context Value → MustacheAST → Text) where
toMustache f = Lambda wrapper
where wrapper c = Right . return . MustacheText . f c
instance ToMustache (Context Value → MustacheAST → String) where
toMustache f = toMustache wrapper
where wrapper c = pack . f c
instance ToMustache (MustacheAST → Either String MustacheAST) where
toMustache f = Lambda $ const f
instance ToMustache (MustacheAST → Either String Text) where
toMustache f = Lambda wrapper
where wrapper _ = fmap (return . MustacheText) . f
instance ToMustache (MustacheAST → Either String String) where
toMustache f = toMustache (fmap pack . f)
instance ToMustache (MustacheAST → Text) where
toMustache f = toMustache (Right . f ∷ MustacheAST -> Either String Text)
instance ToMustache (MustacheAST → String) where
toMustache f = toMustache (pack . 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
object ∷ [(Text, Value)] → Value
object = Object . HM.fromList
(~>) ∷ ToMustache m ⇒ Text → m → KeyValuePair
(~>) t = (t, ) . toMustache
(~=) ∷ Aeson.ToJSON j ⇒ Text → j → KeyValuePair
(~=) t = (t ~>) . Aeson.toJSON
(~~>) ∷ (Conversion t Text, ToMustache m) ⇒ t → m → KeyValuePair
(~~>) = (~>) . convert
(~~=) ∷ (Conversion t Text, Aeson.ToJSON j) ⇒ t → j → KeyValuePair
(~~=) = (~=) . convert
toMustacheText ∷ Conversion t Text ⇒ t → Value
toMustacheText = String . convert
mFromJSON ∷ Aeson.ToJSON j ⇒ j → Value
mFromJSON = toMustache . Aeson.toJSON
data MustacheTemplate = MustacheTemplate { name ∷ String
, ast ∷ MustacheAST
, partials ∷ [MustacheTemplate]
} deriving (Show)