Crates.io | poppable-path |
lib.rs | poppable-path |
version | |
source | src |
created_at | 2025-01-08 21:01:43.011434 |
updated_at | 2025-01-08 21:01:43.011434 |
description | A trait for removing the last component of a path-like thing |
homepage | |
repository | |
max_upload_size | |
id | 1509072 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
This Rust crate provides the [Poppable] trait for removing the last component of [Path]-like things.
If you are like me1, you sometimes end up writing a lot of generic code involving traits with provided methods. For example something like
trait PathGenerator<'a> {
/// Something path-like that may or may not depend on the lifetime `'a`
type Path: AsRef<std::path::Path>;
fn path(&'a self) -> Self::Path;
fn dir(&'a self) -> Option<PathBuf> {
let path = self.path().as_ref().to_owned();
if path.is_dir() {
Some(path)
} else if !path.pop() {
None
} else if path.is_dir() {
Some(path)
} else {
None
}
}
}
Which includes a maybe very unnecessary allocation in the form of a conversion
to PathBuf
. If we knew that the Self::Path
returned by PathGenerator::path
was &'a Path
, we could use Path::parent
rather than PathBuf::pop
. If we
knew it was PathBuf
we could just mutate and return that value directly.
The purpose of this crate is helping in these situations. Because if we can have our cake and eat it we have our cake and eat eet:
trait PathGenerator<'a> {
type Path: Poppable + AsRef<std::path::Path>;
fn path(&'a self) -> Self::Path;
fn dir(&'a self) -> Option<Self::Path> {
let mut path = self.path();
if path.as_ref().is_dir() {
Some(path)
} else if !path.pop() {
None
} else if path.as_ref().is_dir() {
Some(path)
} else {
None
}
}
}
This work is licensed under the MIT license. See the LICENSE file for details.
an idiot ↩