{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings #-} module Generator.Esqueleto where import AST import Data.Maybe import qualified Data.Text as T import Data.List import Text.Shakespeare.Text hiding (toText) hsBinOp :: BinOp -> String hsBinOp op = case op of Eq -> "==." Ne -> "!=." Lt -> "<." Gt -> ">." Le -> "<=." Ge -> ">=." Like -> "`like`" Ilike -> "`ilike`" hsListOp op = case op of In -> "`in_`" NotIn -> "`notIn`" type Context = [(EntityName, VariableName)] ctxLookupEntity :: Context -> VariableName -> Maybe EntityName ctxLookupEntity ctx vn = maybe Nothing (\(en,_) -> Just en) $ find (\(_,vn') -> vn == vn') ctx ctxLookupVariable :: Context -> EntityName -> Maybe VariableName ctxLookupVariable ctx en = maybe Nothing (\(_,vn) -> Just vn) $ find (\(en',_) -> en == en') ctx coerceType :: Maybe BinOp -> String -> String coerceType (Just op) s | op `elem` [Like, Ilike] = "(" ++ s ++ " :: Text)" | otherwise = s coerceType _ s = s hsFieldRef :: Context -> Maybe BinOp -> FieldRef -> String hsFieldRef ctx _ (FieldRefId vn) = vn ++ " ^. " ++ (fromJust $ ctxLookupEntity ctx vn) ++ "Id" hsFieldRef ctx _ (FieldRefNormal vn fn) = vn ++ " ^. " ++ (fromJust $ ctxLookupEntity ctx vn) ++ (upperFirst fn) hsFieldRef _ _ FieldRefAuthId = "(val authId)" hsFieldRef _ op (FieldRefPathParam p) = "(val " ++ coerceType op ("p" ++ show p) ++ ")" hsFieldRef _ op FieldRefLocalParam = "(val " ++ coerceType op "localParam" ++ ")" hsOrderBy :: Context -> (FieldRef, SortDir) -> String hsOrderBy ctx (f,d) = dir d ++ "(" ++ hsFieldRef ctx Nothing f ++ ")" where dir SortAsc = "asc " dir SortDesc = "desc " hsValExpr :: Context -> BinOp -> ValExpr -> String hsValExpr ctx op ve = case ve of FieldExpr fr -> hsFieldRef ctx (Just op) fr ConstExpr fv -> "(val " ++ show fv ++ ")" ConcatExpr e1 e2 -> "(" ++ hsValExpr ctx op e1 ++ ") ++. (" ++ hsValExpr ctx op e2 ++ ")" hsListFieldRef :: Context -> FieldRef -> String hsListFieldRef ctx (FieldRefId vn) = vn ++ " ^. " ++ (fromJust $ ctxLookupEntity ctx vn) ++ "Id" hsListFieldRef ctx (FieldRefNormal vn fn) = vn ++ " ^. " ++ (fromJust $ ctxLookupEntity ctx vn) ++ (upperFirst fn) hsListFieldRef _ FieldRefAuthId = "(valList authId" hsListFieldRef _ (FieldRefPathParam p) = "(valList p" ++ show p ++ ")" hsListFieldRef _ FieldRefLocalParam = "(valList localParam)" hsExpr :: Context-> Expr -> String hsExpr ctx expr = case expr of AndExpr e1 e2 -> "(" ++ hsExpr ctx e1 ++ ") &&. (" ++ hsExpr ctx e2 ++ ")" OrExpr e1 e2 -> "(" ++ hsExpr ctx e1 ++ ") ||. (" ++ hsExpr ctx e2 ++ ")" NotExpr e -> "not_ (" ++ hsExpr ctx e ++ ")" BinOpExpr e1 op e2 -> "(" ++ hsValExpr ctx op e1 ++ ") " ++ hsBinOp op ++ " (" ++ hsValExpr ctx op e2 ++ ")" ListOpExpr fr1 op fr2 -> "(" ++ hsListFieldRef ctx fr1 ++ ") " ++ hsListOp op ++ " (" ++ hsListFieldRef ctx fr2 ++ ")"