Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking issue for Path::relative_from stabilization #23284

Closed
brson opened this issue Mar 11, 2015 · 24 comments · Fixed by #30943
Closed

Tracking issue for Path::relative_from stabilization #23284

brson opened this issue Mar 11, 2015 · 24 comments · Fixed by #30943
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. P-medium Medium priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@brson
Copy link
Contributor

brson commented Mar 11, 2015

Path::relative_from removes the common prefix from a path, e.g. /foo/bar relative_from /foo yields bar.

The old path_relative_from would calculate the relative path from two points on the file system, e.g. the relative path from /foo/bar to /foo/baz/qux is ../baz/qux. This is a useful operation.

Nominating because I think either relative_from is named wrong or is not useful.

@brson
Copy link
Contributor Author

brson commented Mar 11, 2015

cc #23283

@aturon
Copy link
Member

aturon commented Mar 12, 2015

cc me

@aturon
Copy link
Member

aturon commented Mar 12, 2015

Note that the reason the new semantics was adopted has to do with symlinks (the same reason we do not normalize ..). We'll need to discuss this further, but for now it's plausible to leave this function unstable.

@pnkfelix
Copy link
Member

Function is not yet stable, so this need not be milestoned. P-high, not 1.0.

@pnkfelix pnkfelix added P-medium Medium priority and removed I-nominated labels Mar 19, 2015
@lilyball
Copy link
Contributor

Path::relative_from made more sense back when we auto-normalized paths. The idea was if you joined the result to the first path, you'd get the second path. Since we don't normalize like that anymore, that behavior doesn't work.

It's still a potentially useful operation, but because of symlinks, there are two different behaviors that might be desired:

  1. The current behavior where joining the result onto the first path unambiguously refers to the same thing the second path does, even if there's symlinks (which basically means base needs to be a prefix of self)
  2. The old behavior where the result can start with ../ components. Symlinks mean traversing the base path and then traversing the returned relative path may not put you in the same directory that traversing theself` path does. But this operation is useful when either you're working with a path-based system that doesn't care about symlinks, or you've already resolved symlinks in the paths you're working with.

Based on that I think it's reasonable to provide both implementations. The former might want to be called something like strip_prefix() instead. the latter could continue to be called relative_from.

@aturon aturon changed the title New Path::relative_from is less useful than old Path::path_relative_from Tracking issue for Path::relative_from stabilization Aug 12, 2015
@aturon aturon added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. labels Aug 12, 2015
@withoutboats
Copy link
Contributor

Nominating because I think either relative_from is named wrong or is not useful.

Just noting that I have found this function useful. I think it would probably make more sense to name it something like strip_prefix though.

@rgardner
Copy link
Contributor

rgardner commented Nov 6, 2015

I too have found this function useful. What has to happen to stabilize this?

@JanLikar
Copy link
Contributor

This should be stabilized or a similar function should be proposed.

@qmx
Copy link
Member

qmx commented Nov 30, 2015

since @mbrubeck pointed me here for my usecase too, here it comes:

let path = Path::new("/might/be/something/a");
assert_eq!(path.relative_from(Path::new("/might/be")), Path::new("something/a"));

I'm more than fine on renaming it to strip_prefix.

@aturon
Copy link
Member

aturon commented Nov 30, 2015

👍 for the strip_prefix proposal (or something like it). I'd have no problem stabilizing the function with such a clear name.

re: timing, after the 1.6 beta is cut (next week) we will triage all unstable APIs and select a batch for 1.7 stabilization. I'll make sure this one is up for discussion.

@huonw
Copy link
Member

huonw commented Dec 16, 2015

Maybe it could be trim instead of strip, to match the methods on str?

@alexcrichton
Copy link
Member

🔔 This issue is now entering its final comment period for stabilization 🔔

The libs team likes the name strip_prefix, but the trim suggestion is also tempting!

@alexcrichton alexcrichton added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed I-nominated labels Dec 17, 2015
@JanLikar
Copy link
Contributor

str's trim strips both leading and trailing whitespaces, so I prefer strip.

@retep998
Copy link
Member

Just pointing out that Windows treats .. as just removing the last component and completely disregards symlinks. Therefore relative_from or whatever it gets renamed to should be okay with .. on Windows at least.

@rgardner
Copy link
Contributor

👍 to strip_prefix. It's more verbose than trim, but more clearly defines the operation being performed.

let path = Path::new("/home/user/code");
let home = env::home_dir().unwrap();
path.relative_from(home);
path.strip_prefix(home);
path.trim(home);

@huonw
Copy link
Member

huonw commented Jan 12, 2016

I wonder if this should return Result<&Path, StripPrefixError> instead of Option<&Path>. I say this because strip_prefix sounds quite definite (it is definitely stripping the prefix), and hence it is an error (rather than just a "meh, it happens") if it doesn't work.

@qmx
Copy link
Member

qmx commented Jan 13, 2016

+1 to explicit error

@withoutboats
Copy link
Contributor

What would be the variants of StripPrefixError?

@huonw
Copy link
Member

huonw commented Jan 13, 2016

I was thinking struct StripPrefixError { _private: () } (possibly with more details about the input paths, I don't know), like, for instance, ParseBoolError.

@BurntSushi
Copy link
Member

I like strip_prefix. Returning a Result seems prudent.

@aturon
Copy link
Member

aturon commented Jan 13, 2016

I'm on board with both the renaming and using Result here.

@alexcrichton
Copy link
Member

The libs team discussed this during triage yesterday and the decision was to stabilize with the name strip_prefix and the tweak of returning a Result.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Jan 16, 2016
This commit stabilizes and deprecates the FCP (final comment period) APIs for
the upcoming 1.7 beta release. The specific APIs which changed were:

Stabilized

* `Path::strip_prefix` (renamed from `relative_from`)
* `path::StripPrefixError` (new error type returned from `strip_prefix`)
* `Ipv4Addr::is_loopback`
* `Ipv4Addr::is_private`
* `Ipv4Addr::is_link_local`
* `Ipv4Addr::is_multicast`
* `Ipv4Addr::is_broadcast`
* `Ipv4Addr::is_documentation`
* `Ipv6Addr::is_unspecified`
* `Ipv6Addr::is_loopback`
* `Ipv6Addr::is_unique_local`
* `Ipv6Addr::is_multicast`
* `Vec::as_slice`
* `Vec::as_mut_slice`
* `String::as_str`
* `String::as_mut_str`
* `<[T]>::clone_from_slice` - the `usize` return value is removed
* `<[T]>::sort_by_key`
* `i32::checked_rem` (and other signed types)
* `i32::checked_neg` (and other signed types)
* `i32::checked_shl` (and other signed types)
* `i32::checked_shr` (and other signed types)
* `i32::saturating_mul` (and other signed types)
* `i32::overflowing_add` (and other signed types)
* `i32::overflowing_sub` (and other signed types)
* `i32::overflowing_mul` (and other signed types)
* `i32::overflowing_div` (and other signed types)
* `i32::overflowing_rem` (and other signed types)
* `i32::overflowing_neg` (and other signed types)
* `i32::overflowing_shl` (and other signed types)
* `i32::overflowing_shr` (and other signed types)
* `u32::checked_rem` (and other unsigned types)
* `u32::checked_neg` (and other unsigned types)
* `u32::checked_shl` (and other unsigned types)
* `u32::saturating_mul` (and other unsigned types)
* `u32::overflowing_add` (and other unsigned types)
* `u32::overflowing_sub` (and other unsigned types)
* `u32::overflowing_mul` (and other unsigned types)
* `u32::overflowing_div` (and other unsigned types)
* `u32::overflowing_rem` (and other unsigned types)
* `u32::overflowing_neg` (and other unsigned types)
* `u32::overflowing_shl` (and other unsigned types)
* `u32::overflowing_shr` (and other unsigned types)
* `ffi::IntoStringError`
* `CString::into_string`
* `CString::into_bytes`
* `CString::into_bytes_with_nul`
* `From<CString> for Vec<u8>`
* `From<CString> for Vec<u8>`
* `IntoStringError::into_cstring`
* `IntoStringError::utf8_error`
* `Error for IntoStringError`

Deprecated

* `Path::relative_from` - renamed to `strip_prefix`
* `Path::prefix` - use `components().next()` instead
* `os::unix::fs` constants - moved to the `libc` crate
* `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize
* `IntoCow` - conflicts with `Into` and may come back later
* `i32::{BITS, BYTES}` (and other integers) - not pulling their weight
* `DebugTuple::formatter` - will be removed
* `sync::Semaphore` - not used enough and confused with system semaphores

Closes rust-lang#23284
cc rust-lang#27709 (still lots more methods though)
Closes rust-lang#27712
Closes rust-lang#27722
Closes rust-lang#27728
Closes rust-lang#27735
Closes rust-lang#27729
Closes rust-lang#27755
Closes rust-lang#27782
Closes rust-lang#27798
@softprops
Copy link

Is strip_prefix a different name for the same behavior found on strings?
https://doc.rust-lang.org/std/string/struct.String.html#method.trim_left_matches

@SimonSapin
Copy link
Contributor

@softprops str::trim_left_matches zero or more instances of the pattern, as many as possible. Path::strip_prefix removes exactly one or returns Err if there isn’t a match. It also only cuts at path separators.

Manishearth added a commit to Manishearth/rust that referenced this issue Jan 17, 2016
This commit stabilizes and deprecates the FCP (final comment period) APIs for
the upcoming 1.7 beta release. The specific APIs which changed were:

Stabilized

* `Path::strip_prefix` (renamed from `relative_from`)
* `path::StripPrefixError` (new error type returned from `strip_prefix`)
* `Ipv4Addr::is_loopback`
* `Ipv4Addr::is_private`
* `Ipv4Addr::is_link_local`
* `Ipv4Addr::is_multicast`
* `Ipv4Addr::is_broadcast`
* `Ipv4Addr::is_documentation`
* `Ipv6Addr::is_unspecified`
* `Ipv6Addr::is_loopback`
* `Ipv6Addr::is_unique_local`
* `Ipv6Addr::is_multicast`
* `Vec::as_slice`
* `Vec::as_mut_slice`
* `String::as_str`
* `String::as_mut_str`
* `<[T]>::clone_from_slice` - the `usize` return value is removed
* `<[T]>::sort_by_key`
* `i32::checked_rem` (and other signed types)
* `i32::checked_neg` (and other signed types)
* `i32::checked_shl` (and other signed types)
* `i32::checked_shr` (and other signed types)
* `i32::saturating_mul` (and other signed types)
* `i32::overflowing_add` (and other signed types)
* `i32::overflowing_sub` (and other signed types)
* `i32::overflowing_mul` (and other signed types)
* `i32::overflowing_div` (and other signed types)
* `i32::overflowing_rem` (and other signed types)
* `i32::overflowing_neg` (and other signed types)
* `i32::overflowing_shl` (and other signed types)
* `i32::overflowing_shr` (and other signed types)
* `u32::checked_rem` (and other unsigned types)
* `u32::checked_shl` (and other unsigned types)
* `u32::saturating_mul` (and other unsigned types)
* `u32::overflowing_add` (and other unsigned types)
* `u32::overflowing_sub` (and other unsigned types)
* `u32::overflowing_mul` (and other unsigned types)
* `u32::overflowing_div` (and other unsigned types)
* `u32::overflowing_rem` (and other unsigned types)
* `u32::overflowing_neg` (and other unsigned types)
* `u32::overflowing_shl` (and other unsigned types)
* `u32::overflowing_shr` (and other unsigned types)
* `ffi::IntoStringError`
* `CString::into_string`
* `CString::into_bytes`
* `CString::into_bytes_with_nul`
* `From<CString> for Vec<u8>`
* `From<CString> for Vec<u8>`
* `IntoStringError::into_cstring`
* `IntoStringError::utf8_error`
* `Error for IntoStringError`

Deprecated

* `Path::relative_from` - renamed to `strip_prefix`
* `Path::prefix` - use `components().next()` instead
* `os::unix::fs` constants - moved to the `libc` crate
* `fmt::{radix, Radix, RadixFmt}` - not used enough to stabilize
* `IntoCow` - conflicts with `Into` and may come back later
* `i32::{BITS, BYTES}` (and other integers) - not pulling their weight
* `DebugTuple::formatter` - will be removed
* `sync::Semaphore` - not used enough and confused with system semaphores

Closes rust-lang#23284
cc rust-lang#27709 (still lots more methods though)
Closes rust-lang#27712
Closes rust-lang#27722
Closes rust-lang#27728
Closes rust-lang#27735
Closes rust-lang#27729
Closes rust-lang#27755
Closes rust-lang#27782
Closes rust-lang#27798
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. P-medium Medium priority T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.