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 |   24 ++++++++++++++++++------
 src/Ganeti/Utils.hs                |    6 ++++++
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/src/Ganeti/DataCollectors/Types.hs 
b/src/Ganeti/DataCollectors/Types.hs
index da2c793..81d8313 100644
--- a/src/Ganeti/DataCollectors/Types.hs
+++ b/src/Ganeti/DataCollectors/Types.hs
@@ -40,23 +40,24 @@ module Ganeti.DataCollectors.Types
   ) where
 
 import Data.Char
+import Data.Ratio
 import qualified Data.Map as Map
 import qualified Data.Sequence as Seq
 import Text.JSON
 
 import Ganeti.Constants as C
 import Ganeti.THH
-import Ganeti.Utils (getCurrentTime)
+import Ganeti.Utils (getCurrentTime, capitalize)
 
 -- | The possible classes a data collector can belong to.
 data DCCategory = DCInstance | DCStorage | DCDaemon | DCHypervisor
-  deriving (Show, Eq)
+  deriving (Show, Eq, Read)
 
 -- | The JSON instance for DCCategory.
 instance JSON DCCategory where
   showJSON = showJSON . map toLower . drop 2 . show
-  readJSON =
-    error "JSON read instance not implemented for type DCCategory"
+  readJSON (JSString s) = Ok (read ("DC" ++ capitalize (fromJSString s)))
+  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
@@ -88,7 +89,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)
@@ -97,7 +106,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]))
diff --git a/src/Ganeti/Utils.hs b/src/Ganeti/Utils.hs
index 4f67006..839794f 100644
--- a/src/Ganeti/Utils.hs
+++ b/src/Ganeti/Utils.hs
@@ -53,6 +53,7 @@ module Ganeti.Utils
   , warn
   , wrap
   , trim
+  , capitalize
   , defaultHead
   , exitIfEmpty
   , splitEithers
@@ -396,6 +397,11 @@ wrap maxWidth = filter (not . null) . map trim . wrap0
 trim :: String -> String
 trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace
 
+-- | Capitalizes the first character of a string.
+capitalize :: String -> String
+capitalize []     = []
+capitalize (x:xs) = toUpper x : xs
+
 -- | A safer head version, with a default value.
 defaultHead :: a -> [a] -> a
 defaultHead def []    = def
-- 
1.7.10.4

Reply via email to