{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wall #-}
module System.Posix.FilePath (
pathSeparator
, isPathSeparator
, searchPathSeparator
, isSearchPathSeparator
, extSeparator
, isExtSeparator
, splitExtension
, takeExtension
, replaceExtension
, dropExtension
, addExtension
, hasExtension
, (<.>)
, splitExtensions
, dropExtensions
, takeExtensions
, splitFileName
, takeFileName
, replaceFileName
, dropFileName
, takeBaseName
, replaceBaseName
, takeDirectory
, replaceDirectory
, combine
, (</>)
, splitPath
, joinPath
, splitDirectories
, hasTrailingPathSeparator
, addTrailingPathSeparator
, dropTrailingPathSeparator
, isRelative
, isAbsolute
, module System.Posix.ByteString.FilePath
) where
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import System.Posix.ByteString.FilePath
import Data.Char (ord)
import Data.Maybe (isJust)
import Data.Word (Word8)
import Control.Arrow (second)
pathSeparator :: Word8
pathSeparator :: Word8
pathSeparator = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'/'
isPathSeparator :: Word8 -> Bool
isPathSeparator :: Word8 -> Bool
isPathSeparator = (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
pathSeparator)
searchPathSeparator :: Word8
searchPathSeparator :: Word8
searchPathSeparator = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
':'
isSearchPathSeparator :: Word8 -> Bool
isSearchPathSeparator :: Word8 -> Bool
isSearchPathSeparator = (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
searchPathSeparator)
extSeparator :: Word8
extSeparator :: Word8
extSeparator = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Char -> Int
ord Char
'.'
isExtSeparator :: Word8 -> Bool
isExtSeparator :: Word8 -> Bool
isExtSeparator = (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
extSeparator)
splitExtension :: RawFilePath -> (RawFilePath, ByteString)
splitExtension :: RawFilePath -> (RawFilePath, RawFilePath)
splitExtension RawFilePath
x = if RawFilePath -> Bool
BS.null RawFilePath
basename
then (RawFilePath
x,RawFilePath
BS.empty)
else (RawFilePath -> RawFilePath -> RawFilePath
BS.append RawFilePath
path (RawFilePath -> RawFilePath
BS.init RawFilePath
basename),Word8 -> RawFilePath -> RawFilePath
BS.cons Word8
extSeparator RawFilePath
fileExt)
where
(RawFilePath
path,RawFilePath
file) = RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw RawFilePath
x
(RawFilePath
basename,RawFilePath
fileExt) = (Word8 -> Bool) -> RawFilePath -> (RawFilePath, RawFilePath)
BS.breakEnd Word8 -> Bool
isExtSeparator RawFilePath
file
takeExtension :: RawFilePath -> ByteString
takeExtension :: RawFilePath -> RawFilePath
takeExtension = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> b
snd ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath -> (RawFilePath, RawFilePath))
-> RawFilePath
-> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> (RawFilePath, RawFilePath)
splitExtension
replaceExtension :: RawFilePath -> ByteString -> RawFilePath
replaceExtension :: RawFilePath -> RawFilePath -> RawFilePath
replaceExtension RawFilePath
path RawFilePath
ext = RawFilePath -> RawFilePath
dropExtension RawFilePath
path RawFilePath -> RawFilePath -> RawFilePath
<.> RawFilePath
ext
dropExtension :: RawFilePath -> RawFilePath
dropExtension :: RawFilePath -> RawFilePath
dropExtension = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> a
fst ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath -> (RawFilePath, RawFilePath))
-> RawFilePath
-> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> (RawFilePath, RawFilePath)
splitExtension
addExtension :: RawFilePath -> ByteString -> RawFilePath
addExtension :: RawFilePath -> RawFilePath -> RawFilePath
addExtension RawFilePath
file RawFilePath
ext
| RawFilePath -> Bool
BS.null RawFilePath
ext = RawFilePath
file
| Word8 -> Bool
isExtSeparator (RawFilePath -> Word8
BS.head RawFilePath
ext) = RawFilePath -> RawFilePath -> RawFilePath
BS.append RawFilePath
file RawFilePath
ext
| Bool
otherwise = RawFilePath -> [RawFilePath] -> RawFilePath
BS.intercalate (Word8 -> RawFilePath
BS.singleton Word8
extSeparator) [RawFilePath
file, RawFilePath
ext]
(<.>) :: RawFilePath -> ByteString -> RawFilePath
<.> :: RawFilePath -> RawFilePath -> RawFilePath
(<.>) = RawFilePath -> RawFilePath -> RawFilePath
addExtension
hasExtension :: RawFilePath -> Bool
hasExtension :: RawFilePath -> Bool
hasExtension = Maybe Int -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Int -> Bool)
-> (RawFilePath -> Maybe Int) -> RawFilePath -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> RawFilePath -> Maybe Int
BS.elemIndex Word8
extSeparator (RawFilePath -> Maybe Int)
-> (RawFilePath -> RawFilePath) -> RawFilePath -> Maybe Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> RawFilePath
takeFileName
splitExtensions :: RawFilePath -> (RawFilePath, ByteString)
splitExtensions :: RawFilePath -> (RawFilePath, RawFilePath)
splitExtensions RawFilePath
x = if RawFilePath -> Bool
BS.null RawFilePath
basename
then (RawFilePath
path,RawFilePath
fileExt)
else (RawFilePath -> RawFilePath -> RawFilePath
BS.append RawFilePath
path RawFilePath
basename,RawFilePath
fileExt)
where
(RawFilePath
path,RawFilePath
file) = RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw RawFilePath
x
(RawFilePath
basename,RawFilePath
fileExt) = (Word8 -> Bool) -> RawFilePath -> (RawFilePath, RawFilePath)
BS.break Word8 -> Bool
isExtSeparator RawFilePath
file
dropExtensions :: RawFilePath -> RawFilePath
dropExtensions :: RawFilePath -> RawFilePath
dropExtensions = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> a
fst ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath -> (RawFilePath, RawFilePath))
-> RawFilePath
-> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> (RawFilePath, RawFilePath)
splitExtensions
takeExtensions :: RawFilePath -> ByteString
takeExtensions :: RawFilePath -> RawFilePath
takeExtensions = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> b
snd ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath -> (RawFilePath, RawFilePath))
-> RawFilePath
-> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> (RawFilePath, RawFilePath)
splitExtensions
splitFileName :: RawFilePath -> (RawFilePath, RawFilePath)
splitFileName :: RawFilePath -> (RawFilePath, RawFilePath)
splitFileName RawFilePath
x = if RawFilePath -> Bool
BS.null RawFilePath
path
then (RawFilePath
"./", RawFilePath
file)
else (RawFilePath
path,RawFilePath
file)
where
(RawFilePath
path,RawFilePath
file) = RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw RawFilePath
x
takeFileName :: RawFilePath -> RawFilePath
takeFileName :: RawFilePath -> RawFilePath
takeFileName = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> b
snd ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath -> (RawFilePath, RawFilePath))
-> RawFilePath
-> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> (RawFilePath, RawFilePath)
splitFileName
replaceFileName :: RawFilePath -> ByteString -> RawFilePath
replaceFileName :: RawFilePath -> RawFilePath -> RawFilePath
replaceFileName RawFilePath
x RawFilePath
y = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> a
fst (RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw RawFilePath
x) RawFilePath -> RawFilePath -> RawFilePath
</> RawFilePath
y
dropFileName :: RawFilePath -> RawFilePath
dropFileName :: RawFilePath -> RawFilePath
dropFileName = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> a
fst ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath -> (RawFilePath, RawFilePath))
-> RawFilePath
-> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> (RawFilePath, RawFilePath)
splitFileName
takeBaseName :: RawFilePath -> ByteString
takeBaseName :: RawFilePath -> RawFilePath
takeBaseName = RawFilePath -> RawFilePath
dropExtension (RawFilePath -> RawFilePath)
-> (RawFilePath -> RawFilePath) -> RawFilePath -> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> RawFilePath
takeFileName
replaceBaseName :: RawFilePath -> ByteString -> RawFilePath
replaceBaseName :: RawFilePath -> RawFilePath -> RawFilePath
replaceBaseName RawFilePath
path RawFilePath
name = RawFilePath -> RawFilePath -> RawFilePath
combineRaw RawFilePath
dir (RawFilePath
name RawFilePath -> RawFilePath -> RawFilePath
<.> RawFilePath
ext)
where
(RawFilePath
dir,RawFilePath
file) = RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw RawFilePath
path
ext :: RawFilePath
ext = RawFilePath -> RawFilePath
takeExtension RawFilePath
file
takeDirectory :: RawFilePath -> RawFilePath
takeDirectory :: RawFilePath -> RawFilePath
takeDirectory RawFilePath
x = case () of
() | RawFilePath
x RawFilePath -> RawFilePath -> Bool
forall a. Eq a => a -> a -> Bool
== RawFilePath
"/" -> RawFilePath
x
| RawFilePath -> Bool
BS.null RawFilePath
res Bool -> Bool -> Bool
&& Bool -> Bool
not (RawFilePath -> Bool
BS.null RawFilePath
file) -> RawFilePath
file
| Bool
otherwise -> RawFilePath
res
where
res :: RawFilePath
res = (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a, b) -> a
fst ((RawFilePath, RawFilePath) -> RawFilePath)
-> (RawFilePath, RawFilePath) -> RawFilePath
forall a b. (a -> b) -> a -> b
$ (Word8 -> Bool) -> RawFilePath -> (RawFilePath, RawFilePath)
BS.spanEnd Word8 -> Bool
isPathSeparator RawFilePath
file
file :: RawFilePath
file = RawFilePath -> RawFilePath
dropFileName RawFilePath
x
replaceDirectory :: RawFilePath -> ByteString -> RawFilePath
replaceDirectory :: RawFilePath -> RawFilePath -> RawFilePath
replaceDirectory RawFilePath
file RawFilePath
dir = RawFilePath -> RawFilePath -> RawFilePath
combineRaw RawFilePath
dir (RawFilePath -> RawFilePath
takeFileName RawFilePath
file)
combine :: RawFilePath -> RawFilePath -> RawFilePath
combine :: RawFilePath -> RawFilePath -> RawFilePath
combine RawFilePath
a RawFilePath
b | Bool -> Bool
not (RawFilePath -> Bool
BS.null RawFilePath
b) Bool -> Bool -> Bool
&& Word8 -> Bool
isPathSeparator (RawFilePath -> Word8
BS.head RawFilePath
b) = RawFilePath
b
| Bool
otherwise = RawFilePath -> RawFilePath -> RawFilePath
combineRaw RawFilePath
a RawFilePath
b
(</>) :: RawFilePath -> RawFilePath -> RawFilePath
</> :: RawFilePath -> RawFilePath -> RawFilePath
(</>) = RawFilePath -> RawFilePath -> RawFilePath
combine
splitPath :: RawFilePath -> [RawFilePath]
splitPath :: RawFilePath -> [RawFilePath]
splitPath = RawFilePath -> [RawFilePath]
splitter
where
splitter :: RawFilePath -> [RawFilePath]
splitter RawFilePath
x
| RawFilePath -> Bool
BS.null RawFilePath
x = []
| Bool
otherwise = case Word8 -> RawFilePath -> Maybe Int
BS.elemIndex Word8
pathSeparator RawFilePath
x of
Maybe Int
Nothing -> [RawFilePath
x]
Just Int
ix -> case (Word8 -> Bool) -> RawFilePath -> Maybe Int
BS.findIndex (Bool -> Bool
not (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
isPathSeparator) (RawFilePath -> Maybe Int) -> RawFilePath -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Int -> RawFilePath -> RawFilePath
BS.drop (Int
ixInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) RawFilePath
x of
Maybe Int
Nothing -> [RawFilePath
x]
Just Int
runlen -> (RawFilePath -> [RawFilePath] -> [RawFilePath])
-> (RawFilePath, [RawFilePath]) -> [RawFilePath]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:) ((RawFilePath, [RawFilePath]) -> [RawFilePath])
-> ((RawFilePath, RawFilePath) -> (RawFilePath, [RawFilePath]))
-> (RawFilePath, RawFilePath)
-> [RawFilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RawFilePath -> [RawFilePath])
-> (RawFilePath, RawFilePath) -> (RawFilePath, [RawFilePath])
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second RawFilePath -> [RawFilePath]
splitter ((RawFilePath, RawFilePath) -> [RawFilePath])
-> (RawFilePath, RawFilePath) -> [RawFilePath]
forall a b. (a -> b) -> a -> b
$ Int -> RawFilePath -> (RawFilePath, RawFilePath)
BS.splitAt (Int
ixInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
runlen) RawFilePath
x
splitDirectories :: RawFilePath -> [RawFilePath]
splitDirectories :: RawFilePath -> [RawFilePath]
splitDirectories RawFilePath
x
| RawFilePath -> Bool
BS.null RawFilePath
x = []
| Word8 -> Bool
isPathSeparator (RawFilePath -> Word8
BS.head RawFilePath
x) = let (RawFilePath
root,RawFilePath
rest) = Int -> RawFilePath -> (RawFilePath, RawFilePath)
BS.splitAt Int
1 RawFilePath
x
in RawFilePath
root RawFilePath -> [RawFilePath] -> [RawFilePath]
forall a. a -> [a] -> [a]
: RawFilePath -> [RawFilePath]
splitter RawFilePath
rest
| Bool
otherwise = RawFilePath -> [RawFilePath]
splitter RawFilePath
x
where
splitter :: RawFilePath -> [RawFilePath]
splitter = (RawFilePath -> Bool) -> [RawFilePath] -> [RawFilePath]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (RawFilePath -> Bool) -> RawFilePath -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> Bool
BS.null) ([RawFilePath] -> [RawFilePath])
-> (RawFilePath -> [RawFilePath]) -> RawFilePath -> [RawFilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> RawFilePath -> [RawFilePath]
BS.split Word8
pathSeparator
joinPath :: [RawFilePath] -> RawFilePath
joinPath :: [RawFilePath] -> RawFilePath
joinPath = (RawFilePath -> RawFilePath -> RawFilePath)
-> RawFilePath -> [RawFilePath] -> RawFilePath
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr RawFilePath -> RawFilePath -> RawFilePath
(</>) RawFilePath
BS.empty
hasTrailingPathSeparator :: RawFilePath -> Bool
hasTrailingPathSeparator :: RawFilePath -> Bool
hasTrailingPathSeparator RawFilePath
x
| RawFilePath -> Bool
BS.null RawFilePath
x = Bool
False
| RawFilePath
x RawFilePath -> RawFilePath -> Bool
forall a. Eq a => a -> a -> Bool
== RawFilePath
"/" = Bool
False
| Bool
otherwise = Word8 -> Bool
isPathSeparator (Word8 -> Bool) -> Word8 -> Bool
forall a b. (a -> b) -> a -> b
$ RawFilePath -> Word8
BS.last RawFilePath
x
addTrailingPathSeparator :: RawFilePath -> RawFilePath
addTrailingPathSeparator :: RawFilePath -> RawFilePath
addTrailingPathSeparator RawFilePath
x = if RawFilePath -> Bool
hasTrailingPathSeparator RawFilePath
x
then RawFilePath
x
else RawFilePath
x RawFilePath -> Word8 -> RawFilePath
`BS.snoc` Word8
pathSeparator
dropTrailingPathSeparator :: RawFilePath -> RawFilePath
dropTrailingPathSeparator :: RawFilePath -> RawFilePath
dropTrailingPathSeparator RawFilePath
x = if RawFilePath -> Bool
hasTrailingPathSeparator RawFilePath
x
then RawFilePath -> RawFilePath
BS.init RawFilePath
x
else RawFilePath
x
isAbsolute :: RawFilePath -> Bool
isAbsolute :: RawFilePath -> Bool
isAbsolute RawFilePath
x
| RawFilePath -> Int
BS.length RawFilePath
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Word8 -> Bool
isPathSeparator (RawFilePath -> Word8
BS.head RawFilePath
x)
| Bool
otherwise = Bool
False
isRelative :: RawFilePath -> Bool
isRelative :: RawFilePath -> Bool
isRelative = Bool -> Bool
not (Bool -> Bool) -> (RawFilePath -> Bool) -> RawFilePath -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> Bool
isAbsolute
splitFileNameRaw :: RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw :: RawFilePath -> (RawFilePath, RawFilePath)
splitFileNameRaw RawFilePath
x = (Word8 -> Bool) -> RawFilePath -> (RawFilePath, RawFilePath)
BS.breakEnd Word8 -> Bool
isPathSeparator RawFilePath
x
combineRaw :: RawFilePath -> RawFilePath -> RawFilePath
combineRaw :: RawFilePath -> RawFilePath -> RawFilePath
combineRaw RawFilePath
a RawFilePath
b | RawFilePath -> Bool
BS.null RawFilePath
a = RawFilePath
b
| RawFilePath -> Bool
BS.null RawFilePath
b = RawFilePath
a
| Word8 -> Bool
isPathSeparator (RawFilePath -> Word8
BS.last RawFilePath
a) = RawFilePath -> RawFilePath -> RawFilePath
BS.append RawFilePath
a RawFilePath
b
| Bool
otherwise = RawFilePath -> [RawFilePath] -> RawFilePath
BS.intercalate (Word8 -> RawFilePath
BS.singleton Word8
pathSeparator) [RawFilePath
a, RawFilePath
b]
_equalFilePath :: RawFilePath -> RawFilePath -> Bool
_equalFilePath :: RawFilePath -> RawFilePath -> Bool
_equalFilePath RawFilePath
a RawFilePath
b = RawFilePath -> RawFilePath
norm RawFilePath
a RawFilePath -> RawFilePath -> Bool
forall a. Eq a => a -> a -> Bool
== RawFilePath -> RawFilePath
norm RawFilePath
b
where
norm :: RawFilePath -> RawFilePath
norm = RawFilePath -> RawFilePath
dropTrailingSlash (RawFilePath -> RawFilePath)
-> (RawFilePath -> RawFilePath) -> RawFilePath -> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> RawFilePath
dropDups (RawFilePath -> RawFilePath)
-> (RawFilePath -> RawFilePath) -> RawFilePath -> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> RawFilePath
dropInitialDot
dropTrailingSlash :: RawFilePath -> RawFilePath
dropTrailingSlash RawFilePath
path
| RawFilePath -> Int
BS.length RawFilePath
path Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& Word8 -> Bool
isPathSeparator (RawFilePath -> Word8
BS.last RawFilePath
path) = RawFilePath -> RawFilePath
BS.init RawFilePath
path
| Bool
otherwise = RawFilePath
path
dropInitialDot :: RawFilePath -> RawFilePath
dropInitialDot RawFilePath
path
| RawFilePath -> Int
BS.length RawFilePath
path Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& Int -> RawFilePath -> RawFilePath
BS.take Int
2 RawFilePath
path RawFilePath -> RawFilePath -> Bool
forall a. Eq a => a -> a -> Bool
== RawFilePath
"./" = Int -> RawFilePath -> RawFilePath
BS.drop Int
2 RawFilePath
path
| Bool
otherwise = RawFilePath
path
dropDups :: RawFilePath -> RawFilePath
dropDups = [RawFilePath] -> RawFilePath
joinPath ([RawFilePath] -> RawFilePath)
-> (RawFilePath -> [RawFilePath]) -> RawFilePath -> RawFilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RawFilePath -> RawFilePath) -> [RawFilePath] -> [RawFilePath]
forall a b. (a -> b) -> [a] -> [b]
map RawFilePath -> RawFilePath
f ([RawFilePath] -> [RawFilePath])
-> (RawFilePath -> [RawFilePath]) -> RawFilePath -> [RawFilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawFilePath -> [RawFilePath]
splitPath
f :: RawFilePath -> RawFilePath
f RawFilePath
component
| RawFilePath -> RawFilePath -> Bool
BS.isSuffixOf RawFilePath
"//" RawFilePath
component = RawFilePath -> RawFilePath
f (RawFilePath -> RawFilePath
BS.init RawFilePath
component)
| Bool
otherwise = RawFilePath
component