Revision ef8b6bcf src/Ganeti/Utils.hs
b/src/Ganeti/Utils.hs | ||
---|---|---|
36 | 36 |
, formatTable |
37 | 37 |
, printTable |
38 | 38 |
, parseUnit |
39 |
, parseUnitAssumeBinary |
|
39 | 40 |
, plural |
40 | 41 |
, niceSort |
41 | 42 |
, niceSortKey |
... | ... | |
212 | 213 |
formatTable (header:rows) isnum |
213 | 214 |
|
214 | 215 |
-- | Converts a unit (e.g. m or GB) into a scaling factor. |
215 |
parseUnitValue :: (Monad m) => String -> m Rational |
|
216 |
parseUnitValue unit |
|
216 |
parseUnitValue :: (Monad m) => Bool -> String -> m Rational
|
|
217 |
parseUnitValue noDecimal unit
|
|
217 | 218 |
-- binary conversions first |
218 | 219 |
| null unit = return 1 |
219 | 220 |
| unit == "m" || upper == "MIB" = return 1 |
... | ... | |
226 | 227 |
| otherwise = fail $ "Unknown unit '" ++ unit ++ "'" |
227 | 228 |
where upper = map toUpper unit |
228 | 229 |
kbBinary = 1024 :: Rational |
229 |
kbDecimal = 1000 :: Rational
|
|
230 |
kbDecimal = if noDecimal then kbBinary else 1000
|
|
230 | 231 |
decToBin = kbDecimal / kbBinary -- factor for 1K conversion |
231 | 232 |
mbFactor = decToBin * decToBin -- twice the factor for just 1K |
232 | 233 |
|
... | ... | |
234 | 235 |
-- |
235 | 236 |
-- Input must be in the format NUMBER+ SPACE* [UNIT]. If no unit is |
236 | 237 |
-- specified, it defaults to MiB. Return value is always an integral |
237 |
-- value in MiB. |
|
238 |
parseUnit :: (Monad m, Integral a, Read a) => String -> m a
|
|
239 |
parseUnit str = |
|
238 |
-- value in MiB; if the first argument is True, all kilos are binary.
|
|
239 |
parseUnitEx :: (Monad m, Integral a, Read a) => Bool -> String -> m a
|
|
240 |
parseUnitEx noDecimal str =
|
|
240 | 241 |
-- TODO: enhance this by splitting the unit parsing code out and |
241 | 242 |
-- accepting floating-point numbers |
242 | 243 |
case (reads str::[(Int, String)]) of |
243 | 244 |
[(v, suffix)] -> |
244 | 245 |
let unit = dropWhile (== ' ') suffix |
245 | 246 |
in do |
246 |
scaling <- parseUnitValue unit |
|
247 |
scaling <- parseUnitValue noDecimal unit
|
|
247 | 248 |
return $ truncate (fromIntegral v * scaling) |
248 | 249 |
_ -> fail $ "Can't parse string '" ++ str ++ "'" |
249 | 250 |
|
251 |
-- | Tries to extract number and scale from the given string. |
|
252 |
-- |
|
253 |
-- Input must be in the format NUMBER+ SPACE* [UNIT]. If no unit is |
|
254 |
-- specified, it defaults to MiB. Return value is always an integral |
|
255 |
-- value in MiB. |
|
256 |
parseUnit :: (Monad m, Integral a, Read a) => String -> m a |
|
257 |
parseUnit = parseUnitEx False |
|
258 |
|
|
259 |
-- | Tries to extract a number and scale from a given string, taking |
|
260 |
-- all kilos to be binary. |
|
261 |
parseUnitAssumeBinary :: (Monad m, Integral a, Read a) => String -> m a |
|
262 |
parseUnitAssumeBinary = parseUnitEx True |
|
263 |
|
|
250 | 264 |
-- | Unwraps a 'Result', exiting the program if it is a 'Bad' value, |
251 | 265 |
-- otherwise returning the actual contained value. |
252 | 266 |
exitIfBad :: String -> Result a -> IO a |
Also available in: Unified diff