module Text.Liquid.Helpers (
foldM'
, formatNum
, buildLens
, renderPath
, renderExpr
)where
import Data.Aeson.Lens (key, nth)
import Data.Aeson.Types (Value)
import Data.List (intersperse)
import Data.Monoid
import Data.Scientific
import Data.Text (Text)
import qualified Data.Text as T
import Text.Liquid.Types
foldM' :: Monad m
=> (a -> b -> m a)
-> a
-> [b]
-> m a
foldM' _ z [] = return z
foldM' f z (x:xs) = do
z' <- f z x
z' `seq` foldM' f z' xs
formatNum :: Scientific
-> Text
formatNum s | isInteger s =
maybe T.empty (T.pack . show) (toBoundedInteger s :: Maybe Int)
| otherwise =
T.pack $ formatScientific Fixed Nothing s
buildLens :: forall (f :: * -> *) . Applicative f
=> JsonVarPath
-> ((Value -> f Value) -> Value -> f Value)
buildLens xs = foldl1 (.) (matchKey <$> xs)
where matchKey (ObjectIndex i) = key i
matchKey (ArrayIndex i) = nth i
renderPath :: JsonVarPath
-> Text
renderPath path = foldl conc T.empty path
where conc :: Text -> VarIndex -> Text
conc l (ObjectIndex r) | T.null l = r
| otherwise = l <> "." <> r
conc l (ArrayIndex r) | T.null l = "[" <> (T.pack $ show r) <> "]"
| otherwise = l <> "[" <> (T.pack $ show r) <> "]"
renderExpr :: Expr
-> Text
renderExpr Noop = mempty
renderExpr (RawText t) = t
renderExpr (Num s) = formatNum s
renderExpr (Variable jp) = renderPath jp
renderExpr (QuoteString t) = "\'" <> t <> "\'"
renderExpr (Equal l r) = (renderExpr l) <> " == " <> (renderExpr r)
renderExpr (NotEqual l r) = (renderExpr l) <> " != " <> (renderExpr r)
renderExpr (GtEqual l r) = (renderExpr l) <> " >= " <> (renderExpr r)
renderExpr (LtEqual l r) = (renderExpr l) <> " <= " <> (renderExpr r)
renderExpr (Gt l r) = (renderExpr l) <> " > " <> (renderExpr r)
renderExpr (Lt l r) = (renderExpr l) <> " < " <> (renderExpr r)
renderExpr (Or l r) = (renderExpr l) <> " or " <> (renderExpr r)
renderExpr (And l r) = (renderExpr l) <> " and " <> (renderExpr r)
renderExpr (Contains l r) = (renderExpr l) <> " contains " <> (renderExpr r)
renderExpr Trueth = "true"
renderExpr Falseth = "false"
renderExpr Nil = "nil"
renderExpr Null = "null"
renderExpr (Truthy x) = renderExpr x
renderExpr (IfClause x) = "{% if " <> renderExpr x <> " %}"
renderExpr (IfKeyClause x) = "{% ifkey " <> renderExpr x <> " %}"
renderExpr (ElsIfClause x) = "{% elsif " <> renderExpr x <> " %}"
renderExpr Else = "{% else %}"
renderExpr (FilterCell n []) = n
renderExpr (FilterCell n opts) = n <> ": " <> (mconcat $ intersperse ", " $ renderExpr <$> opts)
renderExpr (Filter t fs) = renderExpr t <> bar <> (mconcat $ intersperse bar $ renderExpr <$> fs)
where bar = " | "
renderExpr (Output x) = "{{ " <> renderExpr x <> " }}"
renderExpr (TrueStatements xs) = mconcat $ renderExpr <$> xs
renderExpr (IfLogic i
ts@(TrueStatements _)) =
renderExpr i <>
renderExpr ts <>
"{% endif %}"
renderExpr (IfLogic (IfLogic i ts1@(TrueStatements _))
(IfLogic Else ts2@(TrueStatements _))) =
renderExpr i <>
renderExpr ts1 <>
renderExpr Else <>
renderExpr ts2 <>
"{% endif %}"
renderExpr (IfLogic (IfLogic i ts1@(TrueStatements _))
(IfLogic ei@(ElsIfClause _) ts2@(TrueStatements _))) =
renderExpr i <>
renderExpr ts1 <>
renderExpr ei <>
renderExpr ts2 <>
"{% endif %}"
renderExpr (IfLogic (IfLogic i ts1@(TrueStatements _))
(IfLogic (IfLogic ei@(ElsIfClause _) ts2@(TrueStatements _))
(IfLogic Else ts3@(TrueStatements _)))) =
renderExpr i <>
renderExpr ts1 <>
renderExpr ei <>
renderExpr ts2 <>
renderExpr Else <>
renderExpr ts3 <>
"{% endif %}"
renderExpr (CaseLogic s ts) = "{% case " <> renderExpr s <> " %}" <>
(mconcat $ renderCaseLogic <$> ts) <>
"{% endcase %}"
where renderCaseLogic :: (Expr, Expr) -> Text
renderCaseLogic (Else, y) = "{% else %}" <> renderExpr y
renderCaseLogic (x, y) = "{% when " <> renderExpr x <> " %}" <> renderExpr y
renderExpr _ = mempty