|
5 | 5 | -- Maintainer : streamly@composewell.com |
6 | 6 | -- Portability : GHC |
7 | 7 | -- |
8 | | --- File system paths; extensible, high-performance, preserving the OS and |
9 | | --- filesystem encoding. |
| 8 | +-- File system paths that are extensible, high-performance and preserve the OS |
| 9 | +-- and filesystem encoding. |
| 10 | +-- |
| 11 | +-- The 'Path' type is built on top of Streamly's 'Array' type, leveraging all |
| 12 | +-- its operations and advantages—including support for both pinned and unpinned |
| 13 | +-- representations. It is designed for extensibility and fine-grained type |
| 14 | +-- safety. For type-safe adaptations, refer to the |
| 15 | +-- "Streamly.Internal.FileSystem.Path.*" modules. The type also offers a |
| 16 | +-- powerful and flexible path comparison mechanism. |
| 17 | +-- |
| 18 | +-- 'Path' is interconvertible with the 'OsPath' type from the filepath package |
| 19 | +-- at zero runtime cost. While the API is mostly compatible with that of the |
| 20 | +-- filepath package, some differences exist due to a slightly different design |
| 21 | +-- philosophy focused on enhanced safety. |
10 | 22 | -- |
11 | 23 | -- = Rooted Paths vs Branches |
12 | 24 | -- |
13 | | --- To ensure the safety of the append operation, we distinguish between |
14 | | --- rooted paths and branch-type paths. A path that starts from an explicit or |
15 | | --- implicit root in the file system is called a rooted path. For example, |
16 | | --- @\/usr\/bin@ is a rooted path starting from the explicit root directory @/@. |
17 | | --- Similarly, @.\/bin@ is rooted implicitly, hanging from the current directory. |
18 | | --- A path that is not rooted is called a branch; for example, @local\/bin@ is a |
19 | | --- branch. |
| 25 | +-- To ensure the safety of the append operation, we distinguish between rooted |
| 26 | +-- paths and branch-type paths. A path that starts from an explicit or implicit |
| 27 | +-- root in the file system is called a rooted path or an anchored path. For |
| 28 | +-- example, @\/usr\/bin@ is a rooted path starting from the explicit root |
| 29 | +-- directory @/@. Similarly, @.\/bin@ is rooted implicitly, anchored at the |
| 30 | +-- current directory. A path that is not rooted is called a branch or |
| 31 | +-- unanchored path; for example, @local\/bin@ is a branch. |
20 | 32 | -- |
21 | 33 | -- This distinction ensures the safety of the path append operation. You can |
22 | | --- always append a branch to a rooted path or to another branch. However, |
23 | | --- it does not make sense to append one rooted path to another. The default |
24 | | --- append operation in the Path module checks for this and fails if the |
25 | | --- operation is invalid. However, the programmer can force it using the |
26 | | --- unsafe append operation. Alternatively, you can drop the root explicitly |
27 | | --- and use the safe append. |
28 | | --- |
29 | | --- Since we distinguish between rooted and branch-type paths, a separate |
30 | | --- distinction between absolute and relative paths is not required. Both are |
31 | | --- considered rooted paths, and all rooted paths are protected from invalid |
32 | | --- append operations. Only branch-type paths can be appended. |
| 34 | +-- always append a branch to a rooted path or to another branch. However, it |
| 35 | +-- does not make sense to append one rooted path to another. The default append |
| 36 | +-- operation in the Path module checks for this and fails if the operation is |
| 37 | +-- invalid. However, the programmer can force the unsafe behavior by using the |
| 38 | +-- unsafe append operation. Alternatively, you can drop the root explicitly and |
| 39 | +-- use the safe append. |
| 40 | +-- |
| 41 | +-- Rooted vs branch distinction is a stricter form of relative vs absolute path |
| 42 | +-- distinction. Essentially, paths relative to the current directory are also |
| 43 | +-- treated in the same way as absolute paths, from the perspective of an append |
| 44 | +-- operation. Only branch-type paths can be appended to any other path using |
| 45 | +-- safe operations. |
33 | 46 | -- |
34 | 47 | -- = File vs. Directory Paths |
35 | 48 | -- |
|
39 | 52 | -- Therefore, when using the @Path@ type, the append operation allows appending |
40 | 53 | -- to paths even if they lack a trailing separator. |
41 | 54 | -- |
42 | | --- = Compatibility |
| 55 | +-- = Compatibility with the filepath package |
43 | 56 | -- |
44 | | --- Any path type can be converted to the 'FilePath' type using the 'toString' |
45 | | --- operation. Operations to convert to and from 'OsPath' type at zero cost are |
46 | | --- provided in the @streamly-filepath@ package. This is possible because the |
47 | | --- types use an underlying representation which is compatible with the 'OsPath' |
48 | | --- type. |
| 57 | +-- Any path type can be converted to the 'FilePath' type from the filepath |
| 58 | +-- package by using the 'toString' operation. Operations to convert to and from |
| 59 | +-- the 'OsPath' type at zero cost are provided in the @streamly-filepath@ |
| 60 | +-- package. Zero-cost interconversion is possible because the 'Path' type use |
| 61 | +-- an underlying representation which is compatible with the 'OsPath' type. |
49 | 62 | -- |
50 | 63 | -- = Path Creation Quasiquoter |
51 | 64 | -- |
52 | 65 | -- The 'path' quasiquoter is useful in creating valid paths that are checked |
53 | 66 | -- during the compile time. |
54 | | --- |
55 | | --- |
56 | 67 |
|
57 | 68 | module Streamly.FileSystem.Path |
58 | 69 | ( |
|
0 commit comments