Revision d12f50b2 htools/Ganeti/HTools/Luxi.hs

b/htools/Ganeti/HTools/Luxi.hs
39 39
import qualified Ganeti.HTools.Group as Group
40 40
import qualified Ganeti.HTools.Node as Node
41 41
import qualified Ganeti.HTools.Instance as Instance
42
import Ganeti.HTools.Utils (fromJVal, annotateResult, tryFromObj, asJSObject)
42
import Ganeti.HTools.Utils (fromJVal, annotateResult, tryFromObj, asJSObject,
43
                            fromObj)
43 44

  
44 45
-- * Utility functions
45 46

  
46
-- | Ensure a given JSValue is actually a JSArray.
47
toArray :: (Monad m) => JSValue -> m [JSValue]
48
toArray v =
49
    case v of
50
      JSArray arr -> return arr
51
      o -> fail ("Invalid input, expected array but got " ++ show o)
52

  
53 47
-- | Get values behind \"data\" part of the result.
54 48
getData :: (Monad m) => JSValue -> m JSValue
55
getData v =
56
    case v of
57
      JSObject o ->
58
          case fromJSObject o of
59
            [("data", jsdata), ("fields", _)] -> return jsdata
60
            x -> fail $ "Invalid input, expected two-element list but got "
61
                              ++ show x
62
      x -> fail ("Invalid input, expected dict entry but got " ++ show x)
63

  
64
-- | Get [(status, value)] list for each element queried.
65
toPairs :: (Monad m) => JSValue -> m [[(JSValue, JSValue)]]
66
toPairs (JSArray arr) = do
67
  arr' <- mapM toArray arr -- list of resulting elements
68
  arr'' <- mapM (mapM toArray) arr' -- list of list of [status, value]
69
  return $ map (map (\a -> (a!!0, a!!1))) arr'' -- FIXME: hackish
70
toPairs o = fail ("Invalid input, expected array but got " ++ show o)
49
getData (JSObject o) = fromObj (fromJSObject o) "data"
50
getData x = fail $ "Invalid input, expected dict entry but got " ++ show x
51

  
52
-- | Converts a (status, value) into m value, if possible.
53
parseQueryField :: (Monad m) => JSValue -> m (JSValue, JSValue)
54
parseQueryField (JSArray [status, result]) = return (status, result)
55
parseQueryField o =
56
    fail $ "Invalid query field, expected (status, value) but got " ++ show o
57

  
58
-- | Parse a result row.
59
parseQueryRow :: (Monad m) => JSValue -> m [(JSValue, JSValue)]
60
parseQueryRow (JSArray arr) = mapM parseQueryField arr
61
parseQueryRow o =
62
    fail $ "Invalid query row result, expected array but got " ++ show o
63

  
64
-- | Parse an overall query result and get the [(status, value)] list
65
-- for each element queried.
66
parseQueryResult :: (Monad m) => JSValue -> m [[(JSValue, JSValue)]]
67
parseQueryResult (JSArray arr) = mapM parseQueryRow arr
68
parseQueryResult o =
69
    fail $ "Invalid query result, expected array but got " ++ show o
71 70

  
72 71
-- | Prepare resulting output as parsers expect it.
73 72
extractArray :: (Monad m) => JSValue -> m [JSValue]
74
extractArray v =  do
75
  arr <- getData v >>= toPairs
76
  return $ map (JSArray. map snd) arr
73
extractArray v =
74
  getData v >>= parseQueryResult >>= (return . map (JSArray . map snd))
77 75

  
78 76
-- | Annotate errors when converting values with owner/attribute for
79 77
-- better debugging.

Also available in: Unified diff