Copyright | (c) Boris Buliga, 2014 |
---|---|
License | MIT |
Maintainer | d12frosted@icloud.com |
Stability | experimental |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
FilePath
is very deceptive, because it's just a synonym for String
, so actually it can be anything - your mothers name or path to file you want to edit. Just look at the type signature of function readFile
:
readFile :: FilePath -> IO String
You can translate it as follows:
readFile :: String -> IO String
Well, it is known that IO
actions are dangerous by themselves. And here comes another problem - you need to be sure that the path you pass to function is at least well constructed. For this purpose you can use well known FilePath
data type. It solves a lot of problems and comes beefed with multiple cool utilities. And also it is build around Text
instead of String
. Awesome!
So why do we need yet another path library? The answer is simple - we want to use paths like $HOME/.app.cfg
, ~/.zshrc
or /full/path/to/existing/file/or/dir
in our code without any additional overhead. CanonicalPath
is named so because it tries to canonicalize given path (FilePath
or Text
) using canonicalizePath
function. It also will extract any variables it finds in path (like $VARNAME
, %VARNAME%
and special ~/
). But these steps both may fail. Thats why this library provides functions that return
or Maybe
CanonicalPath
.Either
Text
CanonicalPath
CanonicalPath
also comes with additional useful property. When it is created, it points to real file or directory. Honestly, it can't guarantee that this path will refer to existing file or directory always (someone can remove or move it to another path - and it's almost impossible to be aware of such cruelty), but you can always reconstruct CanonicalPath
.
One more thing about path canonicalization. As I mentioned before, under the hood it uses canonicalizePath
function. So here are two warnings. Firstly, it behaves differently on different platforms. Sometime too damn differently. So you better watch your steps. Secodly, it's impossible to guarantee that the implication same file/dir <=> same canonicalizedPath
holds in either direction: this function can make only a best-effort attempt.
Happy Haskell Hacking!
- data CanonicalPath
- canonicalPath :: MonadIO m => FilePath -> m CanonicalPath
- canonicalPath' :: MonadIO m => Text -> m CanonicalPath
- canonicalPathM :: MonadIO m => FilePath -> m (Maybe CanonicalPath)
- canonicalPathM' :: MonadIO m => Text -> m (Maybe CanonicalPath)
- canonicalPathE :: MonadIO m => FilePath -> m (Either Text CanonicalPath)
- canonicalPathE' :: MonadIO m => Text -> m (Either Text CanonicalPath)
- unsafePath :: CanonicalPath -> FilePath
- readFile :: MonadIO m => CanonicalPath -> m Text
- writeFile :: MonadIO m => CanonicalPath -> Text -> m ()
- writeFile' :: MonadIO m => CanonicalPath -> FilePath -> Text -> m ()
- appendFile :: MonadIO m => CanonicalPath -> Text -> m ()
- fromText :: Text -> FilePath
- toText :: FilePath -> Either Text Text
- toText' :: CanonicalPath -> Text
- fromPrelude :: FilePath -> FilePath
- toPrelude :: FilePath -> FilePath
Abstract Type
Constructors
canonicalPath :: MonadIO m => FilePath -> m CanonicalPath Source
Unsafe constructor of CanonicalPath
. In case of any problems it will error
.
Example:
>>>
canonicalPath "$HOME"
CanonicalPath "/Users/your-user-name"
>>>
canonicalPath "unknown"
*** Exception: Path does not exist (no such file or directory): unknown
Since 0.1.0.0
canonicalPath' :: MonadIO m => Text -> m CanonicalPath Source
Version of canonicalPath
that takes Text
instead of FilePath
.
Since 0.2.1.0
canonicalPathM :: MonadIO m => FilePath -> m (Maybe CanonicalPath) Source
Constructs
.Maybe
CanonicalPath
>>>
canonicalPathM "~"
Just CanonicalPath "Users/your-user-name"
>>>
canonicalPathM "unknown"
Nothing
Since 0.1.0.0
canonicalPathM' :: MonadIO m => Text -> m (Maybe CanonicalPath) Source
Version of canonicalPathM
that takes Text
instead of FilePath
.
Since 0.2.1.0
canonicalPathE :: MonadIO m => FilePath -> m (Either Text CanonicalPath) Source
Constructs Either
Text
CanonicalPath
.
>>>
canonicalPathE "~/"
Right CanonicalPath "/Users/your-user-name"
>>>
canonicalPathE "$HOME/this-folder-does-not-exist"
Left "Path does not exist (no such file or directory): /Users/your-user-name/this-folder-does-not-exist"
Since 0.1.0.0
canonicalPathE' :: MonadIO m => Text -> m (Either Text CanonicalPath) Source
Version of canonicalPathE
that takes Text
instead of FilePath
.
Since 0.2.1.0
unsafePath :: CanonicalPath -> FilePath Source
Convert CanonicalPath
to Filesystem.FilePath
.
Since 0.1.0.0
Some IO functions
readFile :: MonadIO m => CanonicalPath -> m Text Source
readFile file
function reads a file and returns the contents of the file as a Text
. The file is read lazily, on demand, as with getContents.
Since 0.1.1.0
writeFile :: MonadIO m => CanonicalPath -> Text -> m () Source
writeFile file txt
writes txt to the file.
Since 0.1.1.0
writeFile' :: MonadIO m => CanonicalPath -> FilePath -> Text -> m () Source
writeFile' dir file txt
writes txt to the dir/file. Useful, when the file isn't created yet or you don't sure if it exists.
Since 0.1.2.0
appendFile :: MonadIO m => CanonicalPath -> Text -> m () Source
appendFile file txt
appends txt to the file.
Since 0.1.1.0
Conversion functions
toText :: FilePath -> Either Text Text
Attempt to convert a FilePath
to human‐readable text.
If the path is decoded successfully, the result is a Right
containing
the decoded text. Successfully decoded text can be converted back to the
original path using fromText
.
If the path cannot be decoded, the result is a Left
containing an
approximation of the original path. If displayed to the user, this value
should be accompanied by some warning that the path has an invalid
encoding. Approximated text cannot be converted back to the original path.
This function ignores the user’s locale, and assumes all file paths
are encoded in UTF8. If you need to display file paths with an unusual or
obscure encoding, use encode
and then decode them manually.
Since: 0.2
toText' :: CanonicalPath -> Text Source
toText' path
converts CanonicalPath
to Text
.
Since 0.3.0.0