Skip to content

Conversation

@Kinrany
Copy link
Contributor

@Kinrany Kinrany commented Nov 11, 2025

Which issue does this PR close?

Closes #545

Rationale for this change

fn prefix(&self) was the first thing I really wanted to have on Path, as opposed to copying from project to project.

It also benefits from direct access to raw. In userland we have to use paths and collect, and omitting the last item is not trivial.

What changes are included in this PR?

Implementations of everything listed with minimal docs, without tests.

Are there any user-facing changes?

Most of these changes are user-facing.

Internal changes:

  • impl FromIterator delegates most of the logic to impl Expand
  • Path::parts now returns a custom iterator type
  • Added DELIMITER_CHAR

There should be no breaking changes.

@Kinrany
Copy link
Contributor Author

Kinrany commented Nov 11, 2025

Draft for now: everything should work but I'd like to know which of these changes would be welcome, if any. Thanks for maintaining this by the way 🙂

@Kinrany
Copy link
Contributor Author

Kinrany commented Nov 11, 2025

One alternative I'm considering is a fn prefix that takes ownership and avoids cloning. The caller can always clone the original path first if necessary.

src/path/mod.rs Outdated
/// # Performance
///
/// This operation is `O(n)`, similar to calling `.parts().count()` manually.
pub fn len(&self) -> usize {
Copy link
Contributor

@tustvold tustvold Nov 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This collides with the existing len provided by the deref to str

Edit: actually we don't implement deref but still callings this parts_count or something might be less ambiguous

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would renaming empty and is_empty into root and is_root make sense?

@Kinrany Kinrany marked this pull request as ready for review November 23, 2025 17:57
@Kinrany
Copy link
Contributor Author

Kinrany commented Nov 24, 2025

Could I have one more CI run please?

@alamb
Copy link
Contributor

alamb commented Nov 25, 2025

Could I have one more CI run please?

Done

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Kinrany -- these changes look like a nice improvement to me

I think the code needs a few more tests -- doctests are fine (maybe even best) but otherwise this is ready to go in my mind


/// Returns a copy of this [`Path`] with the last path segment removed
///
/// Returns `None` if this path has zero segments.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems pretty similar to https://doc.rust-lang.org/std/path/struct.Path.html#method.parent

Should we call this method parent as well to follow existing convention?

assert_eq!(Path::ROOT.parts().count(), Path::ROOT.parts_count());

let path = path("foo/bar/baz");
assert_eq!(path.parts().count(), path.parts_count());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you also please add an assertion that the count is 3?


Self { raw }
impl<'a, I: Into<PathPart<'a>>> Extend<I> for Path {
fn extend<T: IntoIterator<Item = I>>(&mut self, iter: T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please add tests (perhaps doctests) using this feature explicitly to help others find it?

if s.raw.is_empty() {
continue;
}
self.raw.push(DELIMITER_CHAR);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some tests showing how this works for:

  1. Empty iterators
  2. Iterator with a single element
  3. Iterator with multiple elements
  4. Extending an existing (non empty) Path? (it looks like maybe this will add an extra / 🤔 )

@alamb alamb self-requested a review November 25, 2025 13:35
@alamb
Copy link
Contributor

alamb commented Nov 25, 2025

CI appears to show some regressions

@Kinrany
Copy link
Contributor Author

Kinrany commented Nov 26, 2025

Thank you, will address!

@alamb alamb marked this pull request as draft November 26, 2025 14:36
@alamb
Copy link
Contributor

alamb commented Nov 26, 2025

marking as draft while CI issues are resolved

@alamb
Copy link
Contributor

alamb commented Nov 26, 2025

please mark it ready for review when it is ready for another look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Path ergonomics

3 participants