module Utils.Drasil.FilePath (
RelativeFile, relativeFile, relFileToStr
) where
import Data.List (foldl')
import System.FilePath (isAbsolute, isValid, hasExtension, splitDirectories)
newtype RelativeFile = RF { RelativeFile -> String
relFileToStr :: String }
deriving RelativeFile -> RelativeFile -> Bool
(RelativeFile -> RelativeFile -> Bool)
-> (RelativeFile -> RelativeFile -> Bool) -> Eq RelativeFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RelativeFile -> RelativeFile -> Bool
== :: RelativeFile -> RelativeFile -> Bool
$c/= :: RelativeFile -> RelativeFile -> Bool
/= :: RelativeFile -> RelativeFile -> Bool
Eq
relativeFile :: String -> RelativeFile
relativeFile :: String -> RelativeFile
relativeFile String
fp
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
isCanonical String
fp = String -> RelativeFile
forall a. HasCallStack => String -> a
error (String -> RelativeFile) -> String -> RelativeFile
forall a b. (a -> b) -> a -> b
$ String
"`" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"` is not in canonical form."
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
isValid String
fp = String -> RelativeFile
forall a. HasCallStack => String -> a
error (String -> RelativeFile) -> String -> RelativeFile
forall a b. (a -> b) -> a -> b
$ String
"`" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"` is not a valid file path."
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ String -> Bool
hasExtension String
fp = String -> RelativeFile
forall a. HasCallStack => String -> a
error (String -> RelativeFile) -> String -> RelativeFile
forall a b. (a -> b) -> a -> b
$ String
"`" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"` does not contain a file extension."
| String -> Bool
isAbsolute String
fp = String -> RelativeFile
forall a. HasCallStack => String -> a
error (String -> RelativeFile) -> String -> RelativeFile
forall a b. (a -> b) -> a -> b
$ String
"`" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fp String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"` is an absolute file path, but a relative file path was expected."
| Bool
otherwise = String -> RelativeFile
RF String
fp
isCanonical :: String -> Bool
isCanonical :: String -> Bool
isCanonical String
fp = (Bool -> String -> Bool) -> Bool -> [String] -> Bool
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Bool -> String -> Bool
step Bool
True (String -> [String]
splitDirectories String
fp)
where
step :: Bool -> String -> Bool
step Bool
_ String
"." = Bool
False
step Bool
_ String
".." = Bool
False
step Bool
acc String
_ = Bool
acc