Revision 12e8358c htools/Ganeti/THH.hs

b/htools/Ganeti/THH.hs
56 56
import Control.Monad (liftM)
57 57
import Data.Char
58 58
import Data.List
59
import Data.Maybe (fromMaybe)
59 60
import qualified Data.Set as Set
60 61
import Language.Haskell.TH
61 62

  
......
106 107
customField readfn showfn field =
107 108
  field { fieldRead = Just (varE readfn), fieldShow = Just (varE showfn) }
108 109

  
110
-- | Computes the record name for a given field, based on either the
111
-- string value in the JSON serialisation or the custom named if any
112
-- exists.
109 113
fieldRecordName :: Field -> String
110 114
fieldRecordName (Field { fieldName = name, fieldConstr = alias }) =
111
  maybe (camelCase name) id alias
115
  fromMaybe (camelCase name) alias
112 116

  
113 117
-- | Computes the preferred variable name to use for the value of this
114 118
-- field. If the field has a specific constructor name, then we use a
......
145 149

  
146 150
-- * Common field declarations
147 151

  
152
-- | Timestamp fields description.
148 153
timeStampFields :: [Field]
149 154
timeStampFields =
150 155
    [ defaultField [| 0::Double |] $ simpleField "ctime" [t| Double |]
151 156
    , defaultField [| 0::Double |] $ simpleField "mtime" [t| Double |]
152 157
    ]
153 158

  
159
-- | Serial number fields description.
154 160
serialFields :: [Field]
155 161
serialFields =
156 162
    [ renameField  "Serial" $ simpleField "serial_no" [t| Int |] ]
157 163

  
164
-- | UUID fields description.
158 165
uuidFields :: [Field]
159 166
uuidFields = [ simpleField "uuid" [t| String |] ]
160 167

  
......
196 203
fromRawName :: String -> Name
197 204
fromRawName = mkName . (++ "FromRaw") . ensureLower
198 205

  
199
-- | Converts a name to it's varE/litE representations.
200
--
206
-- | Converts a name to it's varE\/litE representations.
201 207
reprE :: Either String Name -> Q Exp
202 208
reprE = either stringE varE
203 209

  
......
286 292
--
287 293
-- * /name/FromRaw, which (monadically) converts from a raw type to the type
288 294
--
289
-- Note that this is basically just a custom show/read instance,
295
-- Note that this is basically just a custom show\/read instance,
290 296
-- nothing else.
291 297
declareADT :: Name -> String -> [(String, Name)] -> Q [Dec]
292 298
declareADT traw sname cons = do
......
388 394
-- fname (ConStructorTwo {}) = trans_fun("ConStructorTwo")
389 395
-- @
390 396
--
391
-- This builds a custom list of name/string pairs and then uses
392
-- 'genToRaw' to actually generate the function
397
-- This builds a custom list of name\/string pairs and then uses
398
-- 'genToRaw' to actually generate the function.
393 399
genConstrToStr :: (String -> String) -> Name -> String -> Q [Dec]
394 400
genConstrToStr trans_fun name fname = do
395 401
  cnames <- reifyConsNames name
......
487 493
  sigt <- [t| $(conT (mkName "OpCode")) -> JSON.JSValue |]
488 494
  return $ (SigD fname sigt, FunD fname cclauses)
489 495

  
496
-- | Generates load code for a single constructor of the opcode data type.
490 497
loadConstructor :: String -> [Field] -> Q Exp
491 498
loadConstructor sname fields = do
492 499
  let name = mkName sname
......
496 503
      fstmts' = fstmts ++ [NoBindS (AppE (VarE 'return) cval)]
497 504
  return $ DoE fstmts'
498 505

  
506
-- | Generates the loadOpCode function.
499 507
genLoadOpCode :: [(String, [Field])] -> Q (Dec, Dec)
500 508
genLoadOpCode opdefs = do
501 509
  let fname = mkName "loadOpCode"
......
604 612
  ser_decls <- buildObjectSerialisation sname fields
605 613
  return $ declD:ser_decls
606 614

  
615
-- | Generates an object definition: data type and its JSON instance.
607 616
buildObjectSerialisation :: String -> [Field] -> Q [Dec]
608 617
buildObjectSerialisation sname fields = do
609 618
  let name = mkName sname
......
615 624
                 [rdjson, shjson]
616 625
  return $ savedecls ++ [loadsig, loadfn, instdecl]
617 626

  
627
-- | Generates the save object functionality.
618 628
genSaveObject :: (Name -> Field -> Q Exp)
619 629
              -> String -> [Field] -> Q [Dec]
620 630
genSaveObject save_fn sname fields = do
......
636 646
  return [SigD tdname tdsigt, FunD tdname [tclause],
637 647
          SigD fname sigt, ValD (VarP fname) (NormalB cclause) []]
638 648

  
649
-- | Generates the code for saving an object's field, handling the
650
-- various types of fields that we have.
639 651
saveObjectField :: Name -> Field -> Q Exp
640 652
saveObjectField fvar field
641 653
  | fisOptional = [| case $(varE fvar) of
......
651 663
        nameE = stringE (fieldName field)
652 664
        fvarE = varE fvar
653 665

  
666
-- | Generates the showJSON clause for a given object name.
654 667
objectShowJSON :: String -> Q Dec
655 668
objectShowJSON name = do
656 669
  body <- [| JSON.showJSON . $(varE . mkName $ "save" ++ name) |]
657 670
  return $ FunD (mkName "showJSON") [Clause [] (NormalB body) []]
658 671

  
672
-- | Generates the load object functionality.
659 673
genLoadObject :: (Field -> Q (Name, Stmt))
660 674
              -> String -> [Field] -> Q (Dec, Dec)
661 675
genLoadObject load_fn sname fields = do
......
674 688
  return $ (SigD funname sigt,
675 689
            FunD funname [Clause [VarP arg1] (NormalB (DoE fstmts')) []])
676 690

  
691
-- | Generates code for loading an object's field.
677 692
loadObjectField :: Field -> Q (Name, Stmt)
678 693
loadObjectField field = do
679 694
  let name = fieldVariable field
......
693 708

  
694 709
  return (fvar, BindS (VarP fvar) bexp)
695 710

  
711
-- | Builds the readJSON instance for a given object name.
696 712
objectReadJSON :: String -> Q Dec
697 713
objectReadJSON name = do
698 714
  let s = mkName "s"
......
742 758
  fill_decls <- fillParam sname field_pfx fields
743 759
  return $ [declF, declP] ++ ser_decls_f ++ ser_decls_p ++ fill_decls
744 760

  
761
-- | Generates the serialisation for a partial parameter.
745 762
buildPParamSerialisation :: String -> [Field] -> Q [Dec]
746 763
buildPParamSerialisation sname fields = do
747 764
  let name = mkName sname
......
753 770
                 [rdjson, shjson]
754 771
  return $ savedecls ++ [loadsig, loadfn, instdecl]
755 772

  
773
-- | Generates code to save an optional parameter field.
756 774
savePParamField :: Name -> Field -> Q Exp
757 775
savePParamField fvar field = do
758 776
  checkNonOptDef field
......
765 783
                             , Match (ConP 'Just [VarP actualVal])
766 784
                                       (NormalB normalexpr) []
767 785
                             ]
786

  
787
-- | Generates code to load an optional parameter field.
768 788
loadPParamField :: Field -> Q (Name, Stmt)
769 789
loadPParamField field = do
770 790
  checkNonOptDef field
......
785 805
                        $(varNameE $ "f_" ++ fname)
786 806
                        $(varNameE $ "p_" ++ fname) |]) []
787 807

  
808
-- | Builds a function that executes the filling of partial parameter
809
-- from a full copy (similar to Python's fillDict).
788 810
fillParam :: String -> String -> [Field] -> Q [Dec]
789 811
fillParam sname field_pfx fields = do
790 812
  let fnames = map (\fd -> field_pfx ++ fieldRecordName fd) fields

Also available in: Unified diff