Revision 1cb92fac htools/Ganeti/HTools/Utils.hs
b/htools/Ganeti/HTools/Utils.hs | ||
---|---|---|
46 | 46 |
, formatTable |
47 | 47 |
, annotateResult |
48 | 48 |
, defaultGroupID |
49 |
, parseUnit |
|
49 | 50 |
) where |
50 | 51 |
|
51 | 52 |
import Control.Monad (liftM) |
53 |
import Data.Char (toUpper) |
|
52 | 54 |
import Data.List |
53 | 55 |
import Data.Maybe (fromMaybe) |
54 | 56 |
import qualified Text.JSON as J |
... | ... | |
252 | 254 |
-- | Default group UUID (just a string, not a real UUID). |
253 | 255 |
defaultGroupID :: GroupID |
254 | 256 |
defaultGroupID = "00000000-0000-0000-0000-000000000000" |
257 |
|
|
258 |
-- | Tries to extract number and scale from the given string. |
|
259 |
-- |
|
260 |
-- Input must be in the format NUMBER+ SPACE* [UNIT]. If no unit is |
|
261 |
-- specified, it defaults to MiB. Return value is always an integral |
|
262 |
-- value in MiB. |
|
263 |
parseUnit :: (Monad m, Integral a, Read a) => String -> m a |
|
264 |
parseUnit str = |
|
265 |
-- TODO: enhance this by splitting the unit parsing code out and |
|
266 |
-- accepting floating-point numbers |
|
267 |
case reads str of |
|
268 |
[(v, suffix)] -> |
|
269 |
let unit = dropWhile (== ' ') suffix |
|
270 |
upper = map toUpper unit |
|
271 |
siConvert x = x * 1000000 `div` 1048576 |
|
272 |
in case () of |
|
273 |
_ | null unit -> return v |
|
274 |
| unit == "m" || upper == "MIB" -> return v |
|
275 |
| unit == "M" || upper == "MB" -> return $ siConvert v |
|
276 |
| unit == "g" || upper == "GIB" -> return $ v * 1024 |
|
277 |
| unit == "G" || upper == "GB" -> return $ siConvert |
|
278 |
(v * 1000) |
|
279 |
| unit == "t" || upper == "TIB" -> return $ v * 1048576 |
|
280 |
| unit == "T" || upper == "TB" -> return $ |
|
281 |
siConvert (v * 1000000) |
|
282 |
| otherwise -> fail $ "Unknown unit '" ++ unit ++ "'" |
|
283 |
_ -> fail $ "Can't parse string '" ++ str ++ "'" |
Also available in: Unified diff