Crate path_abs [−] [src]
Ergonomic paths and files in rust.
This library aims to provide ergonomic path and file operations to rust with reasonable performance.
This includes:
- Improved error messages, see the Better Errors section.
- Improved type safety. The types specify that a file once existed and was once a certain type. Obviously a file/directory can be deleted/changed by another process.
- More stringent mutability requirements. See the Differing Method Signatures section.
- Cheap cloning: all path types are
Arc
, which a cheap operation compared to filesystem operations and allows more flexibility and ergonomics in the library for relatively low cost.
Better Errors
All errors include the path and action which caused the error, as well as the unaltered
std::io::Error
message. Errors are std::io::Error
, giving almost complete compatibility
with existing code.
set_len
(i.e. truncate a file):
/* */ std::fs::File::set_len(0)
:Invalid argument (os error 22)
path_abs::FileWrite::set_len(0)
:Invalid argument (os error 22) when setting len for /path/to/example/foo.txt
The above error is actually impossible because
FileWrite
is always writeable, andFileRead
does not implementset_len
. However, it is kept for demonstration.
read
(open file for reading):
/**/ std::fs::File::read(path)
:No such file or directory (os error 2)
path_abs::FileRead::read(path)
:No such file or directory (os error 2) when opening example/foo.txt
And every other method has similarily improved errors. If a method does not have pretty error messages please open a ticket.
Exported Path Types
These are the exported Path types. All of them are absolute except for PathArc
, which
is just an Arc<PathBuf>
with methods that have better error reporting.
PathArc
: a reference countedPathBuf
with methods reimplemented with better error messages. Use this for a generic serializable path that may or may not exist.PathAbs
: a reference counted absolute (canonicalized) path that is guaranteed (on initialization) to exist.PathFile
: aPathAbs
that is guaranteed to be a file, with associated methods.PathDir
: aPathAbs
that is guaranteed to be a directory, with associated methods.PathType
: an enum containing either a PathFile or a PathDir. Returned byPathDir::list
In addition, all paths are serializable through serde (even on windows!) by using the crate
stfu8
to encode/decode, allowing ill-formed UTF-16. See
that crate for more details on how the resulting encoding can be edited (by hand) even in the
case of what would be ill-formed UTF-16.
Exported File Types
All File types provide type safe access to their relevant traits. For instance, you can't
read
with a FileWrite
and you can't write
with a FileRead
.
FileRead
: a read-only file handle withpath()
attached and improved error messages. Contains only the methods and trait implementations which are allowed by a read-only file.FileWrite
: a write-only file handle withpath()
attached and improved error messages. Contains only the methods and trait implementations which are allowed by a write-only file.FileEdit
: a read/write file handle withpath()
attached and improved error messages. Contains methods and trait implements for both readable and writeable files.
Differing Method Signatures
The type signatures of the File*
types regarding read
, write
and other methods is
slightly different than std::fs::File
-- they all take &mut
instead of &
. This is to
avoid a common possible footgun.
To demonstrate, imagine the following scenario:
- You pass your open
&File
to a method, which puts it in a thread. This thread constantly callsseek(SeekFrom::Start(10))
- You periodically read from a file expecting new data, but are always getting the same data.
Yes, this is actually allowed by the rust compiler since seek
is implemented for
&File
. Technically this is
still memory safe since the operating system will handle any contention, however many would
argue that it isn't expected that an immutable reference passed to another
function can affect the seek position of a file.
Examples
Recreating Cargo.init
in example/
use std::path::Path; use std::collections::HashSet; use path_abs::{ PathAbs, // absolute path that exists PathDir, // absolute path to a directory PathFile, // absolute path to a file PathType, // enum of Dir or File FileRead, // Open read-only file handler FileWrite, // Open write-only file handler FileEdit, // Open read/write file handler }; let example = Path::new("example"); // Create your paths let project = PathDir::create_all(example)?; let src = PathDir::create(project.join("src"))?; let lib = PathFile::create(src.join("lib.rs"))?; let cargo = PathFile::create(project.join("Cargo.toml"))?; // Write the templates lib.write_str(r#" #[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }"#)?; cargo.write_str(r#" [package] name = "example" version = "0.1.0" authors = ["Garrett Berg <vitiral@gmail.com>"] [dependencies] "#)?; // Put our result into a HashMap so we can assert it let mut result = HashSet::new(); for p in project.list()? { result.insert(p?); } // Create our expected value let mut expected = HashSet::new(); expected.insert(PathType::Dir(src)); expected.insert(PathType::File(cargo)); assert_eq!(expected, result); // ---------------------------------- // Creating types from existing paths // Creating a generic path let lib_path = example.join("src").join("lib.rs"); let abs = PathAbs::new(&lib_path)?; // Or a path with a known type let file = PathType::new(&lib_path) ? .unwrap_file(); // Or use `PathAbs::into_file` let file2 = abs.clone().into_file()?; assert!(abs.is_file()); assert!(file.is_file()); assert!(file2.is_file()); // ---------------------------------- // Opening a File // open read-only using the PathFile method let read = file.read()?; // Or use the type directly: open for appending let write = FileWrite::append(&file)?; // Open for read/write editing. let edit = file.edit()?;
Modules
open |
Open file paths and associated methods. |
Structs
Error |
An error produced by performing an filesystem operation on a |
FileEdit |
A read/write file handle with |
FileRead |
A read-only file handle with |
FileWrite |
A write-only file handle with |
ListDir |
An iterator over |
PathAbs |
An absolute (canonicalized) path that is guaranteed (when created) to exist. |
PathArc |
A |
PathDir |
A |
PathFile |
a |
Enums
PathType |
An an enum containing either a file or a directory. |
Type Definitions
Result |