module System.Console.CmdTheLine.Util
(
fileExists, dirExists, pathExists
, filesExist, dirsExist, pathsExist
, validPath
) where
import Control.Applicative
import Text.PrettyPrint
import System.Console.CmdTheLine.Common
import System.Console.CmdTheLine.Err
import Control.Monad.IO.Class ( liftIO )
import System.Directory ( doesFileExist, doesDirectoryExist )
import System.FilePath ( isValid )
doesFileOrDirExist :: String -> IO Bool
doesFileOrDirExist = liftA2 (||) <$> doesFileExist <*> doesDirectoryExist
check :: (String -> IO Bool) -> String -> String -> Err String
check test errStr path = do
isDir <- liftIO $ test path
if isDir
then return path
else msgFail $ no errStr path
validate :: (String -> IO Bool) -> String -> Term String -> Term String
validate test errStr = ret . fmap (check test errStr)
validates :: (String -> IO Bool) -> String -> Term [String] -> Term [String]
validates test errStr = ret . fmap (mapM $ check test errStr)
fileExists :: Term String -> Term String
fileExists = validate doesFileExist "file"
dirExists :: Term String -> Term String
dirExists = validate doesDirectoryExist "directory"
pathExists :: Term String -> Term String
pathExists = validate doesFileOrDirExist "file or directory"
filesExist :: Term [String] -> Term [String]
filesExist = validates doesFileExist "file"
dirsExist :: Term [String] -> Term [String]
dirsExist = validates doesDirectoryExist "directory"
pathsExist :: Term [String] -> Term [String]
pathsExist = validates doesFileOrDirExist "file or directory"
validPath :: Term String -> Term String
validPath = ret . fmap check
where
check str = if isValid str then return str else msgFail $ failDoc str
failDoc str = quotes (text str) <+> text "is not a valid file path."