-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Support for well-typed paths
--   
--   Support for well-typed paths.
@package path
@version 0.6.1


-- | Internal types and functions.
module Path.Internal

-- | Path of some base and type.
--   
--   The type variables are:
--   
--   <ul>
--   <li><tt>b</tt> — base, the base location of the path; absolute or
--   relative.</li>
--   <li><tt>t</tt> — type, whether file or directory.</li>
--   </ul>
--   
--   Internally is a string. The string can be of two formats only:
--   
--   <ol>
--   <li>File format: <tt>file.txt</tt>, <tt>foo/bar.txt</tt>,
--   <tt>/foo/bar.txt</tt></li>
--   <li>Directory format: <tt>foo/</tt>, <tt>/foo/bar/</tt></li>
--   </ol>
--   
--   All directories end in a trailing separator. There are no duplicate
--   path separators <tt>//</tt>, no <tt>..</tt>, no <tt>./</tt>, no
--   <tt>~/</tt>, etc.
newtype Path b t
Path :: FilePath -> Path b t

-- | Helper function: check if the filepath has any parent directories in
--   it. This handles the logic of checking for different path separators
--   on Windows.
hasParentDir :: FilePath -> Bool

-- | Normalized file path representation for the relative path root
relRootFP :: FilePath

-- | Convert to a <a>FilePath</a> type.
--   
--   All directories have a trailing slash, so if you want no trailing
--   slash, you can use <a>dropTrailingPathSeparator</a> from the filepath
--   package.
toFilePath :: Path b t -> FilePath
instance GHC.Classes.Eq (Path.Internal.Path b t)
instance GHC.Classes.Ord (Path.Internal.Path b t)
instance GHC.Show.Show (Path.Internal.Path b t)
instance Control.DeepSeq.NFData (Path.Internal.Path b t)
instance Data.Aeson.Types.ToJSON.ToJSON (Path.Internal.Path b t)
instance Data.Hashable.Class.Hashable (Path.Internal.Path b t)


-- | This library provides a well-typed representation of paths in a
--   filesystem directory tree. A path is represented by a number of path
--   components separated by a path separator which is a <tt>/</tt> on
--   POSIX systems and can be a <tt>/</tt> or <tt>\</tt> on Windows.
--   
--   The root of the tree is represented by a <tt>/</tt> on POSIX and a
--   drive letter followed by a <tt>/</tt> or <tt>\</tt> on Windows (e.g.
--   <tt>C:\</tt>). Paths can be absolute or relative. An absolute path
--   always starts from the root of the tree (e.g. <tt>/x/y</tt>) whereas a
--   relative path never starts with the root (e.g. <tt>x/y</tt>). Just
--   like we represent the notion of an absolute root by "<tt>/</tt>", the
--   same way we represent the notion of a relative root by "<tt>.</tt>".
--   The relative root denotes the directory which contains the first
--   component of a relative path.
module Path

-- | Path of some base and type.
--   
--   The type variables are:
--   
--   <ul>
--   <li><tt>b</tt> — base, the base location of the path; absolute or
--   relative.</li>
--   <li><tt>t</tt> — type, whether file or directory.</li>
--   </ul>
--   
--   Internally is a string. The string can be of two formats only:
--   
--   <ol>
--   <li>File format: <tt>file.txt</tt>, <tt>foo/bar.txt</tt>,
--   <tt>/foo/bar.txt</tt></li>
--   <li>Directory format: <tt>foo/</tt>, <tt>/foo/bar/</tt></li>
--   </ol>
--   
--   All directories end in a trailing separator. There are no duplicate
--   path separators <tt>//</tt>, no <tt>..</tt>, no <tt>./</tt>, no
--   <tt>~/</tt>, etc.
data Path b t

-- | An absolute path.
data Abs

-- | A relative path; one without a root. Note that a <tt>..</tt> path
--   component to represent the parent directory is not allowed by this
--   library.
data Rel

-- | A file path.
data File

-- | A directory path.
data Dir

-- | Exceptions that can occur during path operations.
data PathException
InvalidAbsDir :: FilePath -> PathException
InvalidRelDir :: FilePath -> PathException
InvalidAbsFile :: FilePath -> PathException
InvalidRelFile :: FilePath -> PathException
NotAProperPrefix :: FilePath -> FilePath -> PathException

-- | Construct a <a>Path</a> <a>Abs</a> <a>Dir</a> using QuasiQuotes.
--   
--   <pre>
--   [absdir|/|]
--   
--   [absdir|/home/chris|]
--   </pre>
--   
--   Remember: due to the nature of absolute paths a path like
--   <tt>[absdir|/home/chris|]</tt> may compile on your platform, but it
--   may not compile on another platform (Windows).
absdir :: QuasiQuoter

-- | Construct a <a>Path</a> <a>Rel</a> <a>Dir</a> using QuasiQuotes.
--   
--   <pre>
--   [absdir|/home|]&lt;/&gt;[reldir|chris|]
--   </pre>
reldir :: QuasiQuoter

-- | Construct a <a>Path</a> <a>Abs</a> <a>File</a> using QuasiQuotes.
--   
--   <pre>
--   [absfile|/home/chris/foo.txt|]
--   </pre>
--   
--   Remember: due to the nature of absolute paths a path like
--   <tt>[absdir|/home/chris/foo.txt|]</tt> may compile on your platform,
--   but it may not compile on another platform (Windows).
absfile :: QuasiQuoter

-- | Construct a <a>Path</a> <a>Rel</a> <a>File</a> using QuasiQuotes.
--   
--   <pre>
--   [absdir|/home/chris|]&lt;/&gt;[relfile|foo.txt|]
--   </pre>
relfile :: QuasiQuoter

-- | Append two paths.
--   
--   The following cases are valid and the equalities hold:
--   
--   <pre>
--   $(mkAbsDir x) &lt;/&gt; $(mkRelDir y) = $(mkAbsDir (x ++ "/" ++ y))
--   </pre>
--   
--   <pre>
--   $(mkAbsDir x) &lt;/&gt; $(mkRelFile y) = $(mkAbsFile (x ++ "/" ++ y))
--   </pre>
--   
--   <pre>
--   $(mkRelDir x) &lt;/&gt; $(mkRelDir y) = $(mkRelDir (x ++ "/" ++ y))
--   </pre>
--   
--   <pre>
--   $(mkRelDir x) &lt;/&gt; $(mkRelFile y) = $(mkRelFile (x ++ "/" ++ y))
--   </pre>
--   
--   The following are proven not possible to express:
--   
--   <pre>
--   $(mkAbsFile …) &lt;/&gt; x
--   </pre>
--   
--   <pre>
--   $(mkRelFile …) &lt;/&gt; x
--   </pre>
--   
--   <pre>
--   x &lt;/&gt; $(mkAbsFile …)
--   </pre>
--   
--   <pre>
--   x &lt;/&gt; $(mkAbsDir …)
--   </pre>
(</>) :: Path b Dir -> Path Rel t -> Path b t
infixr 5 </>

-- | If the directory in the first argument is a proper prefix of the path
--   in the second argument strip it from the second argument, generating a
--   path relative to the directory. Throws <a>NotAProperPrefix</a> if the
--   directory is not a proper prefix of the path.
--   
--   The following properties hold:
--   
--   <pre>
--   stripProperPrefix x (x &lt;/&gt; y) = y
--   </pre>
--   
--   Cases which are proven not possible:
--   
--   <pre>
--   stripProperPrefix (a :: Path Abs …) (b :: Path Rel …)
--   </pre>
--   
--   <pre>
--   stripProperPrefix (a :: Path Rel …) (b :: Path Abs …)
--   </pre>
--   
--   In other words the bases must match.
stripProperPrefix :: MonadThrow m => Path b Dir -> Path b t -> m (Path Rel t)

-- | Determines if the path in the first parameter is a proper prefix of
--   the path in the second parameter.
--   
--   The following properties hold:
--   
--   <pre>
--   not (x `isProperPrefixOf` x)
--   </pre>
--   
--   <pre>
--   x `isProperPrefixOf` (x &lt;/&gt; y)
--   </pre>
isProperPrefixOf :: Path b Dir -> Path b t -> Bool

-- | Take the parent path component from a path.
--   
--   The following properties hold:
--   
--   <pre>
--   parent (x &lt;/&gt; y) == x
--   parent "/x" == "/"
--   parent "x" == "."
--   </pre>
--   
--   On the root (absolute or relative), getting the parent is idempotent:
--   
--   <pre>
--   parent "/" = "/"
--   parent "." = "."
--   </pre>
parent :: Path b t -> Path b Dir

-- | Extract the file part of a path.
--   
--   The following properties hold:
--   
--   <pre>
--   filename (p &lt;/&gt; a) == filename a
--   </pre>
filename :: Path b File -> Path Rel File

-- | Extract the last directory name of a path.
--   
--   The following properties hold:
--   
--   <pre>
--   dirname $(mkRelDir ".") == $(mkRelDir ".")
--   </pre>
--   
--   <pre>
--   dirname (p &lt;/&gt; a) == dirname a
--   </pre>
dirname :: Path b Dir -> Path Rel Dir

-- | Get extension from given file path.
fileExtension :: Path b File -> String

-- | Add extension to given file path. Throws if the resulting filename
--   does not parse.
--   
--   <pre>
--   &gt;&gt;&gt; addFileExtension "txt $(mkRelFile "foo")
--   "foo.txt"
--   
--   &gt;&gt;&gt; addFileExtension "symbols" $(mkRelFile "Data.List")
--   "Data.List.symbols"
--   
--   &gt;&gt;&gt; addFileExtension ".symbols" $(mkRelFile "Data.List")
--   "Data.List.symbols"
--   
--   &gt;&gt;&gt; addFileExtension "symbols" $(mkRelFile "Data.List.")
--   "Data.List..symbols"
--   
--   &gt;&gt;&gt; addFileExtension ".symbols" $(mkRelFile "Data.List.")
--   "Data.List..symbols"
--   
--   &gt;&gt;&gt; addFileExtension "evil/" $(mkRelFile "Data.List")
--   *** Exception: InvalidRelFile "Data.List.evil/"
--   </pre>
addFileExtension :: MonadThrow m => String -> Path b File -> m (Path b File)

-- | A synonym for <a>addFileExtension</a> in the form of an operator. See
--   more examples there.
--   
--   <pre>
--   &gt;&gt;&gt; $(mkRelFile "Data.List") &lt;.&gt; "symbols"
--   "Data.List.symbols"
--   
--   &gt;&gt;&gt; $(mkRelFile "Data.List") &lt;.&gt; "evil/"
--   *** Exception: InvalidRelFile "Data.List.evil/"
--   </pre>
(<.>) :: MonadThrow m => Path b File -> String -> m (Path b File)
infixr 7 <.>

-- | Replace/add extension to given file path. Throws if the resulting
--   filename does not parse.
setFileExtension :: MonadThrow m => String -> Path b File -> m (Path b File)

-- | A synonym for <a>setFileExtension</a> in the form of an operator.
(-<.>) :: MonadThrow m => Path b File -> String -> m (Path b File)
infixr 7 -<.>

-- | Convert an absolute <a>FilePath</a> to a normalized absolute dir
--   <a>Path</a>.
--   
--   Throws: <a>InvalidAbsDir</a> when the supplied path:
--   
--   <ul>
--   <li>is not an absolute path</li>
--   <li>contains a <tt>..</tt> path component representing the parent
--   directory</li>
--   <li>is not a valid path (See <a>isValid</a>)</li>
--   </ul>
parseAbsDir :: MonadThrow m => FilePath -> m (Path Abs Dir)

-- | Convert a relative <a>FilePath</a> to a normalized relative dir
--   <a>Path</a>.
--   
--   Throws: <a>InvalidRelDir</a> when the supplied path:
--   
--   <ul>
--   <li>is not a relative path</li>
--   <li>is <tt>""</tt></li>
--   <li>contains a <tt>..</tt> path component representing the parent
--   directory</li>
--   <li>is not a valid path (See <a>isValid</a>)</li>
--   </ul>
parseRelDir :: MonadThrow m => FilePath -> m (Path Rel Dir)

-- | Convert an absolute <a>FilePath</a> to a normalized absolute file
--   <a>Path</a>.
--   
--   Throws: <a>InvalidAbsFile</a> when the supplied path:
--   
--   <ul>
--   <li>is not an absolute path</li>
--   <li>is a directory path i.e.<ul><li>has a trailing path
--   separator</li><li>is <tt>.</tt> or ends in <tt>/.</tt></li></ul></li>
--   <li>contains a <tt>..</tt> path component representing the parent
--   directory</li>
--   <li>is not a valid path (See <a>isValid</a>)</li>
--   </ul>
parseAbsFile :: MonadThrow m => FilePath -> m (Path Abs File)

-- | Convert a relative <a>FilePath</a> to a normalized relative file
--   <a>Path</a>.
--   
--   Throws: <a>InvalidRelFile</a> when the supplied path:
--   
--   <ul>
--   <li>is not a relative path</li>
--   <li>is <tt>""</tt></li>
--   <li>is a directory path i.e.<ul><li>has a trailing path
--   separator</li><li>is <tt>.</tt> or ends in <tt>/.</tt></li></ul></li>
--   <li>contains a <tt>..</tt> path component representing the parent
--   directory</li>
--   <li>is not a valid path (See <a>isValid</a>)</li>
--   </ul>
parseRelFile :: MonadThrow m => FilePath -> m (Path Rel File)

-- | Convert to a <a>FilePath</a> type.
--   
--   All directories have a trailing slash, so if you want no trailing
--   slash, you can use <a>dropTrailingPathSeparator</a> from the filepath
--   package.
toFilePath :: Path b t -> FilePath

-- | Convert absolute path to directory to <a>FilePath</a> type.
fromAbsDir :: Path Abs Dir -> FilePath

-- | Convert relative path to directory to <a>FilePath</a> type.
fromRelDir :: Path Rel Dir -> FilePath

-- | Convert absolute path to file to <a>FilePath</a> type.
fromAbsFile :: Path Abs File -> FilePath

-- | Convert relative path to file to <a>FilePath</a> type.
fromRelFile :: Path Rel File -> FilePath

-- | Make a <a>Path</a> <a>Abs</a> Dir'.
--   
--   Remember: due to the nature of absolute paths this (e.g.
--   <tt>/home/foo</tt>) may compile on your platform, but it may not
--   compile on another platform (Windows).
mkAbsDir :: FilePath -> Q Exp

-- | Make a <a>Path</a> <a>Rel</a> <a>Dir</a>.
mkRelDir :: FilePath -> Q Exp

-- | Make a <a>Path</a> <a>Abs</a> <a>File</a>.
--   
--   Remember: due to the nature of absolute paths this (e.g.
--   <tt>/home/foo</tt>) may compile on your platform, but it may not
--   compile on another platform (Windows).
mkAbsFile :: FilePath -> Q Exp

-- | Make a <a>Path</a> <a>Rel</a> <a>File</a>.
mkRelFile :: FilePath -> Q Exp

-- | Same as <a>PathException</a>.

-- | <i>Deprecated: Please use PathException instead.</i>
type PathParseException = PathException

-- | Same as <a>stripProperPrefix</a>.

-- | <i>Deprecated: Please use stripProperPrefix instead.</i>
stripDir :: MonadThrow m => Path b Dir -> Path b t -> m (Path Rel t)

-- | Same as <a>isProperPrefixOf</a>.

-- | <i>Deprecated: Please use isProperPrefixOf instead.</i>
isParentOf :: Path b Dir -> Path b t -> Bool
instance GHC.Classes.Eq Path.PathException
instance GHC.Show.Show Path.PathException
instance Data.Aeson.Types.FromJSON.FromJSON (Path.Internal.Path Path.Abs Path.File)
instance Data.Aeson.Types.FromJSON.FromJSON (Path.Internal.Path Path.Rel Path.File)
instance Data.Aeson.Types.FromJSON.FromJSON (Path.Internal.Path Path.Abs Path.Dir)
instance Data.Aeson.Types.FromJSON.FromJSON (Path.Internal.Path Path.Rel Path.Dir)
instance GHC.Exception.Exception Path.PathException
