@@ -2,38 +2,43 @@ module Data.Abstract.Path
2
2
( dropRelativePrefix
3
3
, joinPaths
4
4
, stripQuotes
5
- , joinUntypedPaths
6
5
) where
7
6
8
7
import Data.Text (Text )
9
8
import qualified Data.Text as T
10
- import System.FilePath.Posix
11
9
import qualified System.Path as Path
12
- import System.Path.PartClass (FileDir )
10
+ import System.Path.PartClass (FileDir ( .. ) )
13
11
14
12
-- | Join two paths a and b. Handles walking up relative directories in b. e.g.
15
13
--
16
14
-- joinPaths "a/b" "../c" == "a/c"
17
15
-- joinPaths "a/b" "./c" == "a/b/c"
18
16
--
19
17
-- Walking beyond the beginning of a just stops when you get to the root of a.
20
- joinUntypedPaths :: FilePath -> FilePath -> FilePath
21
- joinUntypedPaths a b = let bs = splitPath (normalise b)
22
- n = length (filter (== " ../" ) bs)
23
- in normalise $ walkup n a </> joinPath (drop n bs)
18
+ joinPaths :: FileDir fd => Path. AbsRelDir -> Path. Rel fd -> Path. AbsRel fd
19
+ joinPaths = runJP $ switchFileDir (JP joinFilePaths) (JP joinDirPaths) (JP joinFDPaths)
20
+
21
+ newtype JP fd = JP { runJP :: Path. AbsRelDir -> Path. Rel fd -> Path. AbsRel fd }
22
+
23
+ joinDirPaths :: Path. AbsRelDir -> Path. RelDir -> Path. AbsRelDir
24
+ joinDirPaths x y = result isAbs
24
25
where
25
- walkup 0 str = str
26
- walkup n str = walkup (pred n) (takeDirectory str)
26
+ (isAbs, rels, _) = Path. splitPath (Path. normalise $ x Path. </> y)
27
+ (_, fRel) = foldr go (0 , Path. currentDir) rels
28
+ go :: Path. RelDir -> (Integer , Path. RelDir ) -> (Integer , Path. RelDir )
29
+ go rel (i, r)
30
+ | rel == Path. rel " .." = (i + 1 , r)
31
+ | i == 0 = (0 , rel Path. </> r)
32
+ | otherwise = (i - 1 , r)
33
+ result True = Path. toAbsRel $ Path. rootDir Path. </> fRel
34
+ result False = Path. toAbsRel $ fRel
27
35
28
- -- | Join two paths a and b. Handles walking up relative directories in b. e.g.
29
- --
30
- -- joinPaths "a/b" "../c" == "a/c"
31
- -- joinPaths "a/b" "./c" == "a/b/c"
32
- --
33
- -- Walking beyond the beginning of a just stops when you get to the root of a.
34
- -- TODO: Rewrite it with pathtype
35
- joinPaths :: FileDir fd => Path. AbsRelDir -> Path. Rel fd -> Path. AbsRel fd
36
- joinPaths x y= Path. path $ joinUntypedPaths (Path. toString x) (Path. toString y)
36
+
37
+ joinFilePaths :: Path. AbsRelDir -> Path. RelFile -> Path. AbsRelFile
38
+ joinFilePaths x y = let (d, f) = Path. splitFileName y in joinDirPaths x d Path. </> f
39
+
40
+ joinFDPaths :: Path. AbsRelDir -> Path. RelFileDir -> Path. AbsRelFileDir
41
+ joinFDPaths x = Path. toFileDir . joinDirPaths x . Path. dirFromFileDir
37
42
38
43
39
44
stripQuotes :: Text -> Text
0 commit comments