dzen-dhall-1.0.0: src/DzenDhall/Extra.hs
module DzenDhall.Extra where
import Control.Monad
import Control.Monad.Trans.Maybe
import Control.Monad.Trans.Except
import qualified Data.List
import Data.Maybe (catMaybes)
import qualified Data.Text
import Data.Text (Text)
import Time.Types
import System.Directory (findExecutable)
import Control.Concurrent.MVar
import Foreign.StablePtr
nonNegative :: (Num a, Ord a) => a -> a
nonNegative x
| x < 0 = 0
| otherwise = x
positive :: Int -> Int
positive x
| x < 1 = 1
| otherwise = x
spaces :: Int -> Text
spaces w = Data.Text.justifyRight w ' ' ""
showPack :: Show a => a -> Text
showPack = Data.Text.pack . show
loopWhileM :: Monad m => m Bool -> m () -> m ()
loopWhileM pr act = do
b <- pr
when b do
act
loopWhileM pr act
whenJust :: (Monad m, Monoid b) => Maybe a -> (a -> m b) -> m b
whenJust = flip $ maybe (return mempty)
leftToJust :: Either a b -> Maybe a
leftToJust (Left a) = Just a
leftToJust _ = Nothing
withMaybe :: Maybe a -> b -> (a -> b) -> b
withMaybe mb b f = maybe b f mb
withEither :: Either a b -> (a -> c) -> (b -> c) -> c
withEither ei l r = either l r ei
whenLeft :: (Monad m, Monoid b) => Either a b -> (a -> m b) -> m b
whenLeft e f = whenJust (leftToJust e) f
safeHead :: [a] -> Maybe a
safeHead = fmap fst . Data.List.uncons
safeTail :: [a] -> Maybe [a]
safeTail = fmap snd . Data.List.uncons
fromLines :: [Text] -> Text
fromLines = Data.Text.intercalate "\n"
hush :: Either e a -> Maybe a
hush (Left _) = Nothing
hush (Right a) = Just a
throwMaybe :: Monad m => MaybeT m a
throwMaybe = exceptToMaybeT (throwE ())
-- This is a workaround,
-- see https://github.com/vincenthz/hs-hourglass/issues/32
addElapsedP :: ElapsedP -> ElapsedP -> ElapsedP
addElapsedP (ElapsedP e1 (NanoSeconds ns1)) (ElapsedP e2 (NanoSeconds ns2)) =
let notNormalizedNS = ns1 + ns2
(retainedNS, ns) = notNormalizedNS `divMod` 1000000000
in ElapsedP (e1 + e2 + (Elapsed $ Seconds retainedNS)) (NanoSeconds ns)
-- | Returns a list of executables that are not present in PATH.
checkExecutables :: [String] -> IO [String]
checkExecutables executables = do
fmap catMaybes $ forM executables \executable ->
maybe (Just executable) (const Nothing) <$> findExecutable executable
isYes :: String -> Bool
isYes response = response `elem` ["Y", "y", "Yes", "yes", ""]
waitForever :: IO ()
waitForever = do
m <- newEmptyMVar
_ <- newStablePtr m
takeMVar m