module Drasil.FileHandling.Legacy.FilePath (
RelativeFile, relativeFile, relFileToStr
) where
import System.FilePath (isAbsolute, isValid, hasExtension, splitDirectories)
newtype RelativeFile = RF { RelativeFile -> [Char]
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 :: [Char] -> RelativeFile
relativeFile [Char]
fp
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> Bool
isCanonical [Char]
fp = [Char] -> RelativeFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> RelativeFile) -> [Char] -> RelativeFile
forall a b. (a -> b) -> a -> b
$ [Char]
"`" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
fp [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"` is not in canonical form."
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> Bool
isValid [Char]
fp = [Char] -> RelativeFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> RelativeFile) -> [Char] -> RelativeFile
forall a b. (a -> b) -> a -> b
$ [Char]
"`" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
fp [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"` is not a valid file path."
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> Bool
hasExtension [Char]
fp = [Char] -> RelativeFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> RelativeFile) -> [Char] -> RelativeFile
forall a b. (a -> b) -> a -> b
$ [Char]
"`" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
fp [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"` does not contain a file extension."
| [Char] -> Bool
isAbsolute [Char]
fp = [Char] -> RelativeFile
forall a. HasCallStack => [Char] -> a
error ([Char] -> RelativeFile) -> [Char] -> RelativeFile
forall a b. (a -> b) -> a -> b
$ [Char]
"`" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
fp [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
"` is an absolute file path, but a relative file path was expected."
| Bool
otherwise = [Char] -> RelativeFile
RF [Char]
fp
isCanonical :: String -> Bool
isCanonical :: [Char] -> Bool
isCanonical [Char]
fp = (Bool -> [Char] -> Bool) -> Bool -> [[Char]] -> 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 -> [Char] -> Bool
step Bool
True ([Char] -> [[Char]]
splitDirectories [Char]
fp)
where
step :: Bool -> [Char] -> Bool
step Bool
_ [Char]
"." = Bool
False
step Bool
_ [Char]
".." = Bool
False
step Bool
acc [Char]
_ = Bool
acc