Safe Haskell | None |
---|
Utility functions.
Synopsis
- debug :: Show a => a -> a
- debugFn :: Show b => (a -> b) -> a -> a
- debugXy :: Show a => a -> b -> b
- applyIf :: Bool -> (a -> a) -> a -> a
- commaJoin :: [String] -> String
- sepSplit :: Eq a => a -> [a] -> [[a]]
- findFirst :: (Ord a, Enum a) => a -> Set a -> a
- plural :: Int -> String -> String -> String
- ensureQuoted :: String -> String
- stdDev :: [Double] -> Double
- if' :: Bool -> a -> a -> a
- parseChoices :: MonadFail m => String -> String -> [(a, String)] -> m a
- tryRead :: (MonadFail m, Read a) => String -> String -> m a
- readMaybe :: Read a => String -> Maybe a
- formatTable :: [[String]] -> [Bool] -> [[String]]
- printTable :: String -> [String] -> [[String]] -> [Bool] -> String
- parseUnitValue :: MonadFail m => Bool -> String -> m Rational
- parseUnitEx :: (MonadFail m, Integral a, Read a) => Bool -> String -> m a
- parseUnit :: (MonadFail m, Integral a, Read a) => String -> m a
- parseUnitAssumeBinary :: (MonadFail m, Integral a, Read a) => String -> m a
- exitIfBad :: String -> Result a -> IO a
- exitErr :: String -> IO a
- exitWhen :: Bool -> String -> IO ()
- exitUnless :: Bool -> String -> IO ()
- logWarningIfBad :: String -> a -> Result a -> IO a
- tryAndLogIOError :: IO a -> String -> (a -> Result b) -> IO (Result b)
- withDefaultOnIOError :: a -> IO a -> IO a
- warn :: String -> IO ()
- extractKey :: [Either Integer String] -> String -> ([Either Integer String], String)
- niceSort :: [String] -> [String]
- niceSortKey :: (a -> String) -> [a] -> [a]
- rStripSpace :: String -> String
- newUUID :: IO String
- uuidCheckParser :: Parser ()
- isUUID :: String -> Bool
- getCurrentTime :: IO Integer
- getCurrentTimeUSec :: IO Integer
- clockTimeToString :: ClockTime -> String
- clockTimeToCTime :: ClockTime -> EpochTime
- clockTimeToUSec :: ClockTime -> Integer
- cTimeToClockTime :: EpochTime -> ClockTime
- diffClockTimes :: ClockTime -> ClockTime -> TimeDiff
- chompPrefix :: String -> String -> Maybe String
- wrap :: Int -> String -> [String]
- trim :: String -> String
- defaultHead :: a -> [a] -> a
- exitIfEmpty :: String -> [a] -> IO a
- monadicThe :: (Eq a, MonadFail m) => String -> [a] -> m a
- splitEithers :: [Either a b] -> ([a], [b], [Bool])
- recombineEithers :: (Show a, Show b) => [a] -> [b] -> [Bool] -> Result [Either a b]
- resolveAddrHints :: Maybe AddrInfo
- resolveAddr :: Int -> String -> IO (Result (Family, SockAddr))
- setOwnerAndGroupFromNames :: FilePath -> GanetiDaemon -> GanetiGroup -> IO ()
- setOwnerWGroupR :: FilePath -> IO ()
- formatOrdinal :: (Integral a, Show a) => a -> String
- lockFile :: FilePath -> IO (Result Fd)
- type FStat = (EpochTime, FileID, FileOffset)
- nullFStat :: FStat
- buildFileStatus :: FileStatus -> FStat
- getFStat :: FilePath -> IO FStat
- getFStatSafe :: FilePath -> IO FStat
- needsReload :: FStat -> FilePath -> IO (Maybe FStat)
- watchFileEx :: Eq b => Integer -> b -> IORef b -> (a -> Bool) -> IO a -> IO a
- watchFileBy :: FilePath -> Int -> (a -> Bool) -> IO a -> IO a
- watchFile :: Eq a => FilePath -> Int -> a -> IO a -> IO a
- data FilePermissions = FilePermissions {
- fpOwner :: Maybe GanetiDaemon
- fpGroup :: Maybe GanetiGroup
- fpPermissions :: FileMode
- ensurePermissions :: FilePath -> FilePermissions -> IO (Result ())
- safeRenameFile :: FilePermissions -> FilePath -> FilePath -> IO (Result ())
- ordNub :: Ord a => [a] -> [a]
- frequency :: Ord t => [t] -> [(Int, t)]
Debug functions
debugFn :: Show b => (a -> b) -> a -> a Source #
Displays a modified form of the second parameter before returning it.
Miscellaneous
applyIf :: Bool -> (a -> a) -> a -> a Source #
Apply the function if condition holds, otherwise use default value.
sepSplit :: Eq a => a -> [a] -> [[a]] Source #
Split a list on a separator and return a list of lists.
findFirst :: (Ord a, Enum a) => a -> Set a -> a Source #
Finds the first unused element in a set starting from a given base.
ensureQuoted :: String -> String Source #
Ensure a value is quoted if needed.
Mathematical functions
Logical functions
:: Bool | condition |
-> a | "then" result |
-> a | "else" result |
-> a | "then" or "else" result depending on the condition |
"if" as a function, rather than as syntactic sugar.
Parsing utility functions
parseChoices :: MonadFail m => String -> String -> [(a, String)] -> m a Source #
Parse results from readsPrec.
tryRead :: (MonadFail m, Read a) => String -> String -> m a Source #
Safe read
function returning data encapsulated in a Result.
readMaybe :: Read a => String -> Maybe a Source #
Parse a string using the Read
instance.
Succeeds if there is exactly one valid result.
Backport from Text.Read introduced in base-4.6.0.0
formatTable :: [[String]] -> [Bool] -> [[String]] Source #
Format a table of strings to maintain consistent length.
printTable :: String -> [String] -> [[String]] -> [Bool] -> String Source #
Constructs a printable table from given header and rows
parseUnitValue :: MonadFail m => Bool -> String -> m Rational Source #
Converts a unit (e.g. m or GB) into a scaling factor.
parseUnitEx :: (MonadFail m, Integral a, Read a) => Bool -> String -> m a Source #
Tries to extract number and scale from the given string.
Input must be in the format NUMBER+ SPACE* [UNIT]. If no unit is specified, it defaults to MiB. Return value is always an integral value in MiB; if the first argument is True, all kilos are binary.
parseUnit :: (MonadFail m, Integral a, Read a) => String -> m a Source #
Tries to extract number and scale from the given string.
Input must be in the format NUMBER+ SPACE* [UNIT]. If no unit is specified, it defaults to MiB. Return value is always an integral value in MiB.
parseUnitAssumeBinary :: (MonadFail m, Integral a, Read a) => String -> m a Source #
Tries to extract a number and scale from a given string, taking all kilos to be binary.
exitWhen :: Bool -> String -> IO () Source #
Exits with an error message if the given boolean condition if true.
exitUnless :: Bool -> String -> IO () Source #
Exits with an error message unless the given boolean condition
if true, the opposite of exitWhen
.
logWarningIfBad :: String -> a -> Result a -> IO a Source #
tryAndLogIOError :: IO a -> String -> (a -> Result b) -> IO (Result b) Source #
Try an IO interaction, log errors and unfold as a Result
.
withDefaultOnIOError :: a -> IO a -> IO a Source #
Try an IO interaction and return a default value if the interaction throws an IOError.
:: [Either Integer String] | Current (partial) key, reversed |
-> String | Remaining string |
-> ([Either Integer String], String) |
Helper for niceSort
. Computes the key element for a given string.
niceSort :: [String] -> [String] Source #
Sort a list of strings based on digit and non-digit groupings.
Given a list of names [
this function
will sort the list in the logical order a1
, a10
, a11
, a2
][
.a1
, a2
, a10
, a11
]
The sort algorithm breaks each name in groups of either only-digits or no-digits, and sorts based on each group.
Internally, this is not implemented via regexes (like the Python
version), but via actual splitting of the string in sequences of
either digits or everything else, and converting the digit sequences
in Left Integer and the non-digit ones in Right String, at which
point sorting becomes trivial due to the built-in Either
ordering;
we only need one extra step of dropping the key at the end.
niceSortKey :: (a -> String) -> [a] -> [a] Source #
Key-version of niceSort
. We use sortBy
and compare
since we don't want to add an ordering constraint on the a type,
hence the need to only compare the first element of the (key, a)
tuple.on
fst
rStripSpace :: String -> String Source #
Strip space characthers (including newline). As this is expensive, should only be run on small strings.
Returns a random UUID. This is a Linux-specific method as it uses the /proc filesystem.
uuidCheckParser :: Parser () Source #
Parser that doesn't fail on a valid UUIDs (same as "Ganeti.Constants.uuidRegex").
isUUID :: String -> Bool Source #
Checks if the string is a valid UUID as in "Ganeti.Constants.uuidRegex".
getCurrentTime :: IO Integer Source #
Returns the current time as an Integer
representing the number
of seconds from the Unix epoch.
getCurrentTimeUSec :: IO Integer Source #
Returns the current time as an Integer
representing the number
of microseconds from the Unix epoch (hence the need for Integer
).
clockTimeToString :: ClockTime -> String Source #
Convert a ClockTime into a (seconds-only) timestamp.
clockTimeToCTime :: ClockTime -> EpochTime Source #
Convert a ClockTime into a (seconds-only) EpochTime
(AKA time_t
).
clockTimeToUSec :: ClockTime -> Integer Source #
Convert a ClockTime the number of microseconds since the epoch.
cTimeToClockTime :: EpochTime -> ClockTime Source #
Convert a ClockTime into a (seconds-only) EpochTime
(AKA time_t
).
diffClockTimes :: ClockTime -> ClockTime -> TimeDiff Source #
A version of diffClockTimes
that works around ghc bug #2519.
chompPrefix :: String -> String -> Maybe String Source #
Strip a prefix from a string, allowing the last character of the prefix (which is assumed to be a separator) to be absent from the string if the string terminates there.
>>> chompPrefix "foo:bar:" "a:b:c" Nothing
>>> chompPrefix "foo:bar:" "foo:bar:baz" Just "baz"
>>> chompPrefix "foo:bar:" "foo:bar:" Just ""
>>> chompPrefix "foo:bar:" "foo:bar" Just ""
>>> chompPrefix "foo:bar:" "foo:barbaz" Nothing
:: Int | maxWidth |
-> String | string that needs wrapping |
-> [String] | string "broken" in lines |
Breaks a string in lines with length <= maxWidth.
NOTE: The split is OK if:
- It doesn't break a word, i.e. the next line begins with space
(
isSpace . head $ rest
) or the current line ends with space (null revExtra
); - It breaks a very big word that doesn't fit anyway (
null revLine
).
trim :: String -> String Source #
Removes surrounding whitespace. Should only be used in small strings.
defaultHead :: a -> [a] -> a Source #
A safer head version, with a default value.
exitIfEmpty :: String -> [a] -> IO a Source #
A head
version in the I/O monad, for validating parameters
without which we cannot continue.
monadicThe :: (Eq a, MonadFail m) => String -> [a] -> m a Source #
Obtain the unique element of a list in an arbitrary monad.
splitEithers :: [Either a b] -> ([a], [b], [Bool]) Source #
Split an Either
list into two separate lists (containing the
Left
and Right
elements, plus a "trail" list that allows
recombination later.
This is splitter; for recombination, look at recombineEithers
.
The sum of "left" and "right" lists should be equal to the
original list length, and the trail list should be the same length
as well. The entries in the resulting lists are reversed in
comparison with the original list.
recombineEithers :: (Show a, Show b) => [a] -> [b] -> [Bool] -> Result [Either a b] Source #
Recombines two "left" and "right" lists using a "trail"
list into a single Either
list.
This is the counterpart to splitEithers
. It does the opposite
transformation, and the output list will be the reverse of the
input lists. Since splitEithers
also reverses the lists, calling
these together will result in the original list.
Mismatches in the structure of the lists (e.g. inconsistent
lengths) are represented via Bad
; normally this function should
not fail, if lists are passed as generated by splitEithers
.
resolveAddrHints :: Maybe AddrInfo Source #
Default hints for the resolver
resolveAddr :: Int -> String -> IO (Result (Family, SockAddr)) Source #
Resolves a numeric address.
setOwnerAndGroupFromNames :: FilePath -> GanetiDaemon -> GanetiGroup -> IO () Source #
Set the owner and the group of a file (given as names, not numeric id).
setOwnerWGroupR :: FilePath -> IO () Source #
Resets permissions so that the owner can read/write and the group only read. All other permissions are cleared.
formatOrdinal :: (Integral a, Show a) => a -> String Source #
Formats an integral number, appending a suffix.
lockFile :: FilePath -> IO (Result Fd) Source #
Attempt, in a non-blocking way, to obtain a lock on a given file; report back success. Returns the file descriptor so that the lock can be released by closing
buildFileStatus :: FileStatus -> FStat Source #
Computes the file cache data from a FileStatus structure.
getFStat :: FilePath -> IO FStat Source #
Wrapper over buildFileStatus
. This reads the data from the
filesystem and then builds our cache structure.
getFStatSafe :: FilePath -> IO FStat Source #
Safe version of getFStat
, that ignores IOErrors.
needsReload :: FStat -> FilePath -> IO (Maybe FStat) Source #
Check if the file needs reloading
watchFileEx :: Eq b => Integer -> b -> IORef b -> (a -> Bool) -> IO a -> IO a Source #
Until the given point in time (useconds since the epoch), wait for the output of a given method to change and return the new value; make use of the promise that the output only changes if the reference has a value different than the given one.
watchFileBy :: FilePath -> Int -> (a -> Bool) -> IO a -> IO a Source #
Within the given timeout (in seconds), wait for for the output of the given method to satisfy a given predicate and return the new value; make use of the promise that the method will only change its value, if the given file changes on disk. If the file does not exist on disk, return immediately.
watchFile :: Eq a => FilePath -> Int -> a -> IO a -> IO a Source #
Within the given timeout (in seconds), wait for for the output of the given method to change and return the new value; make use of the promise that the method will only change its value, if the given file changes on disk. If the file does not exist on disk, return immediately.
data FilePermissions Source #
Type describing ownership and permissions of newly generated directories and files. All parameters are optional, with nothing meaning that the default value should be left untouched.
FilePermissions | |
|
ensurePermissions :: FilePath -> FilePermissions -> IO (Result ()) Source #
Ensure that a given file or directory has the permissions, and possibly ownerships, as required.
safeRenameFile :: FilePermissions -> FilePath -> FilePath -> IO (Result ()) Source #
Safely rename a file, creating the target directory, if needed.