path-0.5.9: Support for well-typed paths

Copyright© 2015–2016 FP Complete
LicenseBSD 3 clause
MaintainerChris Done <chrisdone@fpcomplete.com>
Stabilityexperimental
Portabilityportable
Safe HaskellNone
LanguageHaskell98

Path

Contents

Description

Support for well-typed paths.

Synopsis

Types

data Path b t Source

Path of some base and type.

Internally is a string. The string can be of two formats only:

  1. File format: file.txt, foo/bar.txt, /foo/bar.txt
  2. Directory format: foo/, /foo/bar/

All directories end in a trailing separator. There are no duplicate path separators //, no .., no ./, no ~/, etc.

Instances

Eq (Path b t) Source

String equality.

The following property holds:

show x == show y ≡ x == y
Ord (Path b t) Source

String ordering.

The following property holds:

show x `compare` show y ≡ x `compare` y
Show (Path b t) Source

Same as toFilePath.

The following property holds:

x == y ≡ show x == show y
NFData (Path b t) Source 
ToJSON (Path b t) Source 
FromJSON (Path Rel Dir) 
FromJSON (Path Rel File) 
FromJSON (Path Abs Dir) 
FromJSON (Path Abs File) 

data Abs Source

An absolute path.

Instances

FromJSON (Path Abs Dir) Source 
FromJSON (Path Abs File) Source 

data Rel Source

A relative path; one without a root. Note that a . as well as any path starting with a .. is not a valid relative path. In other words, a relative path is always strictly under the directory tree to which it is relative.

Instances

FromJSON (Path Rel Dir) Source 
FromJSON (Path Rel File) Source 

data File Source

A file path.

Instances

FromJSON (Path Rel File) Source 
FromJSON (Path Abs File) Source 

data Dir Source

A directory path.

Instances

FromJSON (Path Rel Dir) Source 
FromJSON (Path Abs Dir) Source 

Parsing

parseAbsDir :: MonadThrow m => FilePath -> m (Path Abs Dir) Source

Convert an absolute FilePath to a normalized absolute dir Path.

Throws: PathParseException when the supplied path:

  • is not an absolute path
  • contains a .. anywhere in the path
  • is not a valid path (See isValid)

parseRelDir :: MonadThrow m => FilePath -> m (Path Rel Dir) Source

Convert a relative FilePath to a normalized relative dir Path.

Throws: PathParseException when the supplied path:

  • is not a relative path
  • is any of "", . or ..
  • contains .. anywhere in the path
  • is not a valid path (See isValid)

parseAbsFile :: MonadThrow m => FilePath -> m (Path Abs File) Source

Convert an absolute FilePath to a normalized absolute file Path.

Throws: PathParseException when the supplied path:

  • is not an absolute path
  • has a trailing path separator
  • contains .. anywhere in the path
  • is not a valid path (See isValid)

parseRelFile :: MonadThrow m => FilePath -> m (Path Rel File) Source

Convert a relative FilePath to a normalized relative file Path.

Throws: PathParseException when the supplied path:

  • is not a relative path
  • has a trailing path separator
  • is "", . or ..
  • contains .. anywhere in the path
  • is not a valid path (See isValid)

data PathParseException Source

Exception when parsing a location.

Constructors

mkAbsDir :: FilePath -> Q Exp Source

Make a 'Path Abs Dir'.

Remember: due to the nature of absolute paths this (e.g. /home/foo) may compile on your platform, but it may not compile on another platform (Windows).

mkRelDir :: FilePath -> Q Exp Source

Make a 'Path Rel Dir'.

mkAbsFile :: FilePath -> Q Exp Source

Make a 'Path Abs File'.

Remember: due to the nature of absolute paths this (e.g. /home/foo) may compile on your platform, but it may not compile on another platform (Windows).

mkRelFile :: FilePath -> Q Exp Source

Make a 'Path Rel File'.

Operations

(</>) :: Path b Dir -> Path Rel t -> Path b t Source

Append two paths.

The following cases are valid and the equalities hold:

$(mkAbsDir x) </> $(mkRelDir y) = $(mkAbsDir (x ++ "/" ++ y))
$(mkAbsDir x) </> $(mkRelFile y) = $(mkAbsFile (x ++ "/" ++ y))
$(mkRelDir x) </> $(mkRelDir y) = $(mkRelDir (x ++ "/" ++ y))
$(mkRelDir x) </> $(mkRelFile y) = $(mkRelFile (x ++ "/" ++ y))

The following are proven not possible to express:

$(mkAbsFile …) </> x
$(mkRelFile …) </> x
x </> $(mkAbsFile …)
x </> $(mkAbsDir …)

stripDir :: MonadThrow m => Path b Dir -> Path b t -> m (Path Rel t) Source

Strip directory from path, making it relative to that directory. Throws Couldn'tStripPrefixDir if directory is not a parent of the path.

The following properties hold:

stripDir x (x </> y) = y

Cases which are proven not possible:

stripDir (a :: Path Abs …) (b :: Path Rel …)
stripDir (a :: Path Rel …) (b :: Path Abs …)

In other words the bases must match.

isParentOf :: Path b Dir -> Path b t -> Bool Source

Is p a parent of the given location? Implemented in terms of stripDir. The bases must match.

The following properties hold:

not (x isParentOf x)
x isParentOf (x </> y)

parent :: Path Abs t -> Path Abs Dir Source

Take the absolute parent directory from the absolute path.

The following properties hold:

parent (x </> y) == x

On the root, getting the parent is idempotent:

parent (parent "/") = "/"

filename :: Path b File -> Path Rel File Source

Extract the file part of a path.

The following properties hold:

filename (p </> a) == filename a

dirname :: Path b Dir -> Path Rel Dir Source

Extract the last directory name of a path.

The following properties hold:

dirname (p </> a) == dirname a

Conversion

toFilePath :: Path b t -> FilePath Source

Convert to a FilePath type.

All directories have a trailing slash, so if you want no trailing slash, you can use dropTrailingPathSeparator from the filepath package.

fromAbsDir :: Path Abs Dir -> FilePath Source

Convert absolute path to directory to FilePath type.

fromRelDir :: Path Rel Dir -> FilePath Source

Convert relative path to directory to FilePath type.

fromAbsFile :: Path Abs File -> FilePath Source

Convert absolute path to file to FilePath type.

fromRelFile :: Path Rel File -> FilePath Source

Convert relative path to file to FilePath type.