Revision ebf38064 htools/Ganeti/HTools/Utils.hs

b/htools/Ganeti/HTools/Utils.hs
22 22
-}
23 23

  
24 24
module Ganeti.HTools.Utils
25
    (
26
      debug
27
    , debugFn
28
    , debugXy
29
    , sepSplit
30
    , stdDev
31
    , if'
32
    , select
33
    , applyIf
34
    , commaJoin
35
    , readEitherString
36
    , JSRecord
37
    , loadJSArray
38
    , fromObj
39
    , fromObjWithDefault
40
    , maybeFromObj
41
    , tryFromObj
42
    , fromJVal
43
    , asJSObject
44
    , asObjectList
45
    , fromJResult
46
    , tryRead
47
    , formatTable
48
    , annotateResult
49
    , defaultGroupID
50
    , parseUnit
51
    ) where
25
  ( debug
26
  , debugFn
27
  , debugXy
28
  , sepSplit
29
  , stdDev
30
  , if'
31
  , select
32
  , applyIf
33
  , commaJoin
34
  , readEitherString
35
  , JSRecord
36
  , loadJSArray
37
  , fromObj
38
  , fromObjWithDefault
39
  , maybeFromObj
40
  , tryFromObj
41
  , fromJVal
42
  , asJSObject
43
  , asObjectList
44
  , fromJResult
45
  , tryRead
46
  , formatTable
47
  , annotateResult
48
  , defaultGroupID
49
  , parseUnit
50
  ) where
52 51

  
53 52
import Data.Char (toUpper)
54 53
import Data.List
......
88 87
-- | Split a list on a separator and return an array.
89 88
sepSplit :: Eq a => a -> [a] -> [[a]]
90 89
sepSplit sep s
91
    | null s    = []
92
    | null xs   = [x]
93
    | null ys   = [x,[]]
94
    | otherwise = x:sepSplit sep ys
95
    where (x, xs) = break (== sep) s
96
          ys = drop 1 xs
90
  | null s    = []
91
  | null xs   = [x]
92
  | null ys   = [x,[]]
93
  | otherwise = x:sepSplit sep ys
94
  where (x, xs) = break (== sep) s
95
        ys = drop 1 xs
97 96

  
98 97
-- * Mathematical functions
99 98

  
......
135 134
       -> a            -- ^ first result which has a True condition, or default
136 135
select def = maybe def snd . find fst
137 136

  
138

  
139 137
-- | Annotate a Result with an ownership information.
140 138
annotateResult :: String -> Result a -> Result a
141 139
annotateResult owner (Bad s) = Bad $ owner ++ ": " ++ s
......
195 193
-- value in MiB.
196 194
parseUnit :: (Monad m, Integral a, Read a) => String -> m a
197 195
parseUnit str =
198
    -- TODO: enhance this by splitting the unit parsing code out and
199
    -- accepting floating-point numbers
200
    case reads str of
201
      [(v, suffix)] ->
202
          let unit = dropWhile (== ' ') suffix
203
              upper = map toUpper unit
204
              siConvert x = x * 1000000 `div` 1048576
205
          in case () of
206
               _ | null unit -> return v
207
                 | unit == "m" || upper == "MIB" -> return v
208
                 | unit == "M" || upper == "MB"  -> return $ siConvert v
209
                 | unit == "g" || upper == "GIB" -> return $ v * 1024
210
                 | unit == "G" || upper == "GB"  -> return $ siConvert
211
                                                    (v * 1000)
212
                 | unit == "t" || upper == "TIB" -> return $ v * 1048576
213
                 | unit == "T" || upper == "TB"  -> return $
214
                                                    siConvert (v * 1000000)
215
                 | otherwise -> fail $ "Unknown unit '" ++ unit ++ "'"
216
      _ -> fail $ "Can't parse string '" ++ str ++ "'"
196
  -- TODO: enhance this by splitting the unit parsing code out and
197
  -- accepting floating-point numbers
198
  case reads str of
199
    [(v, suffix)] ->
200
      let unit = dropWhile (== ' ') suffix
201
          upper = map toUpper unit
202
          siConvert x = x * 1000000 `div` 1048576
203
      in case () of
204
           _ | null unit -> return v
205
             | unit == "m" || upper == "MIB" -> return v
206
             | unit == "M" || upper == "MB"  -> return $ siConvert v
207
             | unit == "g" || upper == "GIB" -> return $ v * 1024
208
             | unit == "G" || upper == "GB"  -> return $ siConvert
209
                                                (v * 1000)
210
             | unit == "t" || upper == "TIB" -> return $ v * 1048576
211
             | unit == "T" || upper == "TB"  -> return $
212
                                                siConvert (v * 1000000)
213
             | otherwise -> fail $ "Unknown unit '" ++ unit ++ "'"
214
    _ -> fail $ "Can't parse string '" ++ str ++ "'"

Also available in: Unified diff