module Puppet.Utils
( textElem
, module Data.Monoid
, getDirectoryContents
, takeBaseName
, takeDirectory
, strictifyEither
, nameThread
, scientific2text
) where
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.ByteString as BS
import Data.Monoid
import System.Posix.Directory.ByteString
import qualified Data.Either.Strict as S
import Control.Concurrent (myThreadId)
import GHC.Conc (labelThread)
import Data.Scientific
import Control.Lens
import Data.Aeson.Lens
scientific2text :: Scientific -> T.Text
scientific2text n = T.pack $ case n ^? _Integer of
Just i -> show i
_ -> show n
strictifyEither :: Either a b -> S.Either a b
strictifyEither (Left x) = S.Left x
strictifyEither (Right x) = S.Right x
textElem :: Char -> T.Text -> Bool
textElem c = T.any (==c)
nameThread :: String -> IO ()
nameThread n = myThreadId >>= flip labelThread n
getDirectoryContents :: T.Text -> IO [T.Text]
getDirectoryContents fpath = do
h <- openDirStream (T.encodeUtf8 fpath)
let readHandle = do
fp <- readDirStream h
if BS.null fp
then return []
else fmap (T.decodeUtf8 fp :) readHandle
out <- readHandle
closeDirStream h
return out
takeBaseName :: T.Text -> T.Text
takeBaseName fullname =
let afterLastSlash = last $ T.splitOn "/" fullname
splitExtension = init $ T.splitOn "." afterLastSlash
in T.intercalate "." splitExtension
takeDirectory :: T.Text -> T.Text
takeDirectory "" = "."
takeDirectory "/" = "/"
takeDirectory x =
let res = T.dropWhileEnd (== '/') file
file = dropFileName x
in if T.null res && not (T.null file)
then file
else res
dropFileName :: T.Text -> T.Text
dropFileName = fst . splitFileName
splitFileName :: T.Text -> (T.Text, T.Text)
splitFileName x = (if T.null dir then "./" else dir, name)
where
(dir, name) = splitFileName_ x
splitFileName_ y = (T.reverse b, T.reverse a)
where
(a,b) = T.break (=='/') $ T.reverse y