Στις 24 Σεπ 2013, 1:49 μ.μ., ο/η Michele Tartara <[email protected]> έγραψε:

> On Fri, Sep 20, 2013 at 3:14 PM, Spyros Trigazis <[email protected]> wrote:
> 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"
> 
> Using "read" is always quite dangerous, on input which is not validated. What 
> happens when the result of 
>   ("DC" ++ capitalize (fromJSString s)))
> is not a string corresponding to an actual element of DCCategory? I think the 
> whole program will just crash throwing an exception, which is not nice.
> 
> Therefore, I'm afraid you'll have to list the valid strings and fail in case 
> you receive a string which is none of them.

ack

> 
> Otherwise, have a look at the valFromObj function, which might help you do 
> something similar to what you are doing now (I'm not 100% sure, though, I 
> never used it).
> 
> 
>  -- | 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
> 
> 
> Rest LGTM.
> 
> Thanks,
> Michele

Thanks,
Spyros

> 
> -- 
> Google Germany GmbH
> Dienerstr. 12
> 80331 München
> 
> Registergericht und -nummer: Hamburg, HRB 86891
> Sitz der Gesellschaft: Hamburg
> Geschäftsführer: Graham Law, Christine Elizabeth Flores

Reply via email to