Revision 72375ff8 src/Ganeti/THH.hs
b/src/Ganeti/THH.hs | ||
---|---|---|
50 | 50 |
, Field (..) |
51 | 51 |
, simpleField |
52 | 52 |
, andRestArguments |
53 |
, specialNumericalField |
|
54 |
, timeAsDoubleField |
|
55 | 53 |
, withDoc |
56 | 54 |
, defaultField |
57 | 55 |
, optionalField |
58 | 56 |
, optionalNullSerField |
59 | 57 |
, renameField |
60 | 58 |
, customField |
61 |
, timeStampFields |
|
62 |
, uuidFields |
|
63 |
, serialFields |
|
64 |
, tagsFields |
|
65 |
, TagSet |
|
66 | 59 |
, buildObject |
67 | 60 |
, buildObjectSerialisation |
68 | 61 |
, buildParam |
... | ... | |
80 | 73 |
import Data.List |
81 | 74 |
import Data.Maybe |
82 | 75 |
import qualified Data.Map as M |
83 |
import qualified Data.Set as Set |
|
84 | 76 |
import Language.Haskell.TH |
85 | 77 |
import Language.Haskell.TH.Syntax (lift) |
86 |
import System.Time (ClockTime(..)) |
|
87 | 78 |
|
88 | 79 |
import qualified Text.JSON as JSON |
89 | 80 |
import Text.JSON.Pretty (pp_value) |
... | ... | |
228 | 219 |
optionalNullSerField :: Field -> Field |
229 | 220 |
optionalNullSerField field = field { fieldIsOptional = OptionalSerializeNull } |
230 | 221 |
|
231 |
-- | Wrapper around a special parse function, suitable as field-parsing |
|
232 |
-- function. |
|
233 |
numericalReadFn :: JSON.JSON a => (String -> JSON.Result a) |
|
234 |
-> [(String, JSON.JSValue)] -> JSON.JSValue -> JSON.Result a |
|
235 |
numericalReadFn _ _ v@(JSON.JSRational _ _) = JSON.readJSON v |
|
236 |
numericalReadFn f _ (JSON.JSString x) = f $ JSON.fromJSString x |
|
237 |
numericalReadFn _ _ _ = JSON.Error "A numerical field has to be a number or\ |
|
238 |
\ a string." |
|
239 |
|
|
240 |
-- | Sets the read function to also accept string parsable by the given |
|
241 |
-- function. |
|
242 |
specialNumericalField :: Name -> Field -> Field |
|
243 |
specialNumericalField f field = |
|
244 |
field { fieldRead = Just (appE (varE 'numericalReadFn) (varE f)) } |
|
245 |
|
|
246 |
-- | Creates a new mandatory field that reads time as the (floating point) |
|
247 |
-- number of seconds since the standard UNIX epoch, and represents it in |
|
248 |
-- Haskell as 'ClockTime'. |
|
249 |
timeAsDoubleField :: String -> Field |
|
250 |
timeAsDoubleField fname = |
|
251 |
(simpleField fname [t| ClockTime |]) |
|
252 |
{ fieldRead = Just $ [| \_ -> liftM unTimeAsDoubleJSON . JSON.readJSON |] |
|
253 |
, fieldShow = Just $ [| \c -> (JSON.showJSON $ TimeAsDoubleJSON c, []) |] |
|
254 |
} |
|
255 |
|
|
256 | 222 |
-- | Sets custom functions on a field. |
257 | 223 |
customField :: Name -- ^ The name of the read function |
258 | 224 |
-> Name -- ^ The name of the show function |
... | ... | |
335 | 301 |
loadFnOpt field expr o |
336 | 302 |
= [| $expr >>= maybe (return Nothing) (liftM Just . $(parseFn field o)) |] |
337 | 303 |
|
338 |
-- * Common field declarations |
|
339 |
|
|
340 |
-- | Timestamp fields description. |
|
341 |
timeStampFields :: [Field] |
|
342 |
timeStampFields = map (defaultField [| TOD 0 0 |] . timeAsDoubleField) |
|
343 |
["ctime", "mtime"] |
|
344 |
|
|
345 |
|
|
346 |
-- | Serial number fields description. |
|
347 |
serialFields :: [Field] |
|
348 |
serialFields = |
|
349 |
[ renameField "Serial" $ simpleField "serial_no" [t| Int |] ] |
|
350 |
|
|
351 |
-- | UUID fields description. |
|
352 |
uuidFields :: [Field] |
|
353 |
uuidFields = [ simpleField "uuid" [t| String |] ] |
|
354 |
|
|
355 |
-- | Tag set type alias. |
|
356 |
type TagSet = Set.Set String |
|
357 |
|
|
358 |
-- | Tag field description. |
|
359 |
tagsFields :: [Field] |
|
360 |
tagsFields = [ defaultField [| Set.empty |] $ |
|
361 |
simpleField "tags" [t| TagSet |] ] |
|
362 |
|
|
363 | 304 |
-- * Internal types |
364 | 305 |
|
365 | 306 |
-- | A simple field, in constrast to the customisable 'Field' type. |
Also available in: Unified diff