Implement readJSON functions for DCCategory, DCVersion and
DCKind in Data Collectors's Types to be parsable from a JSON
formatted file. Also, implement a utility function to
capitalize the first character of a string.

Signed-off-by: Spyros Trigazis <[email protected]>
---
 src/Ganeti/DataCollectors/Types.hs |   33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/Ganeti/DataCollectors/Types.hs 
b/src/Ganeti/DataCollectors/Types.hs
index ec55cd5..591b857 100644
--- a/src/Ganeti/DataCollectors/Types.hs
+++ b/src/Ganeti/DataCollectors/Types.hs
@@ -41,8 +41,10 @@ module Ganeti.DataCollectors.Types
   ) where
 
 import Data.Char
+import Data.Ratio
 import qualified Data.Map as Map
 import qualified Data.Sequence as Seq
+import qualified Data.List as L
 import Text.JSON
 
 import Ganeti.Constants as C
@@ -51,17 +53,27 @@ import Ganeti.Utils (getCurrentTime)
 
 -- | The possible classes a data collector can belong to.
 data DCCategory = DCInstance | DCStorage | DCDaemon | DCHypervisor
-  deriving (Show, Eq)
+  deriving (Show, Eq, Read)
 
 -- | Gets the category name and returns it as a string.
 getCategoryName :: DCCategory -> String
 getCategoryName dcc = map toLower . drop 2 . show $ dcc
 
+categoryNames :: [(DCCategory, String)]
+categoryNames =
+  let l = [DCInstance, DCStorage, DCDaemon, DCHypervisor]
+  in zip l (map getCategoryName l)
+
 -- | The JSON instance for DCCategory.
 instance JSON DCCategory where
   showJSON = showJSON . getCategoryName
-  readJSON =
-    error "JSON read instance not implemented for type DCCategory"
+  readJSON (JSString s) =
+    let s' = fromJSString s
+    in case L.find ((== s') . snd) categoryNames of
+         Just (category, _) -> Ok category
+         Nothing -> fail $ "Invalid category name " ++ s' ++ " for type\
+                           \ DCCategory"
+  readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type DCCategory"
 
 -- | The possible status codes of a data collector.
 data DCStatusCode = DCSCOk      -- ^ Everything is OK
@@ -93,7 +105,15 @@ data DCKind = DCKPerf   -- ^ Performance reporting collector
 instance JSON DCKind where
   showJSON DCKPerf   = showJSON (0 :: Int)
   showJSON DCKStatus = showJSON (1 :: Int)
-  readJSON = error "JSON read instance not implemented for type DCKind"
+  readJSON (JSRational _ x) =
+    if denominator x /= 1
+    then fail $ "Invalid JSON value " ++ show x ++ " for type DCKind"
+    else
+      let x' = (fromIntegral . numerator $ x) :: Int
+      in if x' == 0 then Ok DCKPerf
+         else if x' == 1 then Ok DCKStatus
+         else fail $ "Invalid JSON value " ++ show x' ++ " for type DCKind"
+  readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type DCKind"
 
 -- | Type representing the version number of a data collector.
 data DCVersion = DCVerBuiltin | DCVersion String deriving (Show, Eq)
@@ -102,7 +122,10 @@ data DCVersion = DCVerBuiltin | DCVersion String deriving 
(Show, Eq)
 instance JSON DCVersion where
   showJSON DCVerBuiltin = showJSON C.builtinDataCollectorVersion
   showJSON (DCVersion v) = showJSON v
-  readJSON = error "JSON read instance not implemented for type DCVersion"
+  readJSON (JSString s) =
+    if fromJSString s == C.builtinDataCollectorVersion
+    then Ok DCVerBuiltin else Ok . DCVersion $ fromJSString s
+  readJSON v = fail $ "Invalid JSON value " ++ show v ++ " for type DCVersion"
 
 -- | Type for the value field of the above map.
 data CollectorData = CPULoadData (Seq.Seq (Integer, [Int]))
-- 
1.7.10.4

Reply via email to