diff --git a/htools/Ganeti/THH.hs b/htools/Ganeti/THH.hs index 1fe3824eb9b128dc48d33d172682c087e9d309e8..643684650cd91b76ddc30aed5049b68d1d3da3ea 100644 --- a/htools/Ganeti/THH.hs +++ b/htools/Ganeti/THH.hs @@ -236,6 +236,32 @@ appFn :: Exp -> Exp -> Exp appFn f x | f == VarE 'id = x | otherwise = AppE f x +-- | Builds a field for a normal constructor. +buildConsField :: Q Type -> StrictTypeQ +buildConsField ftype = do + ftype' <- ftype + return (NotStrict, ftype') + +-- | Builds a constructor based on a simple definition (not field-based). +buildSimpleCons :: Name -> SimpleObject -> Q Dec +buildSimpleCons tname cons = do + decl_d <- mapM (\(cname, fields) -> do + fields' <- mapM (buildConsField . snd) fields + return $ NormalC (mkName cname) fields') cons + return $ DataD [] tname [] decl_d [''Show, ''Read, ''Eq] + +-- | Generate the save function for a given type. +genSaveSimpleObj :: Name -- ^ Object type + -> String -- ^ Function name + -> SimpleObject -- ^ Object definition + -> (SimpleConstructor -> Q Clause) -- ^ Constructor save fn + -> Q (Dec, Dec) +genSaveSimpleObj tname sname opdefs fn = do + let sigt = AppT (AppT ArrowT (ConT tname)) (ConT ''JSON.JSValue) + fname = mkName sname + cclauses <- mapM fn opdefs + return $ (SigD fname sigt, FunD fname cclauses) + -- * Template code for simple raw type-equivalent ADTs -- | Generates a data type declaration. @@ -573,14 +599,10 @@ genStrOfKey = genConstrToStr ensureLower -- genLuxiOp :: String -> SimpleObject -> Q [Dec] genLuxiOp name cons = do - decl_d <- mapM (\(cname, fields) -> do - fields' <- mapM (\(_, qt) -> - qt >>= \t -> return (NotStrict, t)) - fields - return $ NormalC (mkName cname) fields') - cons - let declD = DataD [] (mkName name) [] decl_d [''Show, ''Read, ''Eq] - (savesig, savefn) <- genSaveLuxiOp cons + let tname = mkName name + declD <- buildSimpleCons tname cons + (savesig, savefn) <- genSaveSimpleObj tname "opToArgs" + cons saveLuxiConstructor req_defs <- declareSADT "LuxiReq" . map (\(str, _) -> ("Req" ++ str, mkName ("luxiReq" ++ str))) $ cons @@ -603,14 +625,6 @@ saveLuxiConstructor (sname, fields) = do else [| JSON.showJSON $(listE flist) |] clause [pat] (normalB finval) [] --- | Generates the main save LuxiOp function. -genSaveLuxiOp :: SimpleObject-> Q (Dec, Dec) -genSaveLuxiOp opdefs = do - sigt <- [t| $(conT (mkName "LuxiOp")) -> JSON.JSValue |] - let fname = mkName "opToArgs" - cclauses <- mapM saveLuxiConstructor opdefs - return $ (SigD fname sigt, FunD fname cclauses) - -- * "Objects" functionality -- | Extract the field's declaration from a Field structure.