-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Correcting Path::components on non-"Unix" platforms #52331
Comments
The This means a backward-compatible option 5 is available: impl<'a> PrefixComponent<'a> {
/// On Windows, returns the parsed prefix data.
///
/// On other platforms, the returned value is unspecified.
#[cfg_attr(
target_os = "redox",
rustc_deprecated(
since = "1.29.0",
reason = "The prefix component is meaningless on Redox. Use `.scheme()` instead",
),
)]
pub fn kind(&self) -> Prefix<'a> { ... }
}
mod redox {
pub trait PrefixComponentExt<'a> {
// Obtains the scheme of the Redox path (URL).
fn scheme(&self) -> &'a OsStr;
}
impl<'a> PrefixComponentExt<'a> for PrefixComponent<'a> {
fn scheme(&self) -> &'a OsStr { self.as_os_str() }
}
} |
What should the return value of PrefixComponent::kind be on Redox? |
Regarding option 5, shouldn't kind() ideally be deprecated on all platforms, with an extension trait for Windows instead? Even though there's probably a lot of software depending on the |
@jackpot51 Maybe DeviceNS? Not that there is any enum variant that fits the purpose correctly at all on Redox, but based on my limited experience with file systems on Windows, AFAIK windows uses "devices" (IoCreateDevice) for filesystems, which would probably apply more than the alternatives, for a Redox scheme. That said, the return value would not make any sense at all, but at least it would make parsing and serialization to and from |
@rustbot label +I-needs-decision I hope this is the right way to ask for some input from the libs-api team. This issue has stagnated for a while without a clear path forward, and it would be nice if we had a way to support multiple platforms that use a path prefix scheme like this other than just Windows. |
One proposed design:
|
Also, we're going to need someone willing to do the design and implementation work here. |
@joshtriplett I will implement whichever design has the highest chance of being upstreamed. |
@joshtriplett can you please help to get upstream consensus on which option from the original post would be best and I will implement it? |
@jackpot51 I don't think attempting to use the existing Given that, that leaves us with:
Windows folks: should we pay the transition cost to allow for new path prefixes, or is that exceedingly unlikely given that the existing prefixes include extensible variants? @rust-lang/libs-api: Does the above plan sound reasonable? (This is orthogonal to questions about how we should handle non-native path types in the future.) |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
Hey Windows Group! This bug has been identified as a good "Windows candidate". cc @arlosi @ChrisDenton @danielframpton @gdr-at-ms @kennykerr @luqmana @lzybkr @nico-abram @retep998 @rylev @sivadeilra @wesleywiser |
If deprecating |
I would like to express support for this as an option, because I think it's conceivable there would be use cases for other OSes expanding on the API in the future (for example, the 3DS horizon OS is another place where we'd like something similar). It doesn't seem ideal in my opinion to add a new |
I will be trying to solve this using the recommendations above. It has been a while, but we are still running into issues with path parsing on Redox and solving this issue would fix most of them. |
We've decided to provide, and use by default, a path format that works without needing prefixes. |
apparently even with Redox switching to the Unix path format, this is still a problem for 3DS Horizon OS (#52331 (comment))? |
That is correct. |
This is also a problem for UEFI. |
Oh, I was working on creating a new issue, but I guess since this has been reopened, I can put my proposal here. UEFI Prefix TypesShell PrefixIf UEFI shell is present, it creates mappings for all partitions/devices that implement Device Path
ProposalI wanted to propose a 2-step plan to improve the handling of such paths, and creating the respective PRs. Step 1Create a private This step will allow isolating Step 2Start adding new public APIs for new prefix capabilities and deprecating Does this seem good? Or maybe there is a better way to go about it? |
@Ayush1325 We discussed this in a recent libs-api meeting. We're not sure what the right path forward is with Path::components(), but we're willing to try out your proposal as an unstable feature to see where we end up. You're welcome to open a tracking issue for it and send PRs to make your changes. (As long as they don't affect stable Rust, of course.) Separately from that, I have some thoughts about another solution, which I will post in a moment. |
I have been wondering for quite a while if a (better) solution could be to fully deprecate It gave me the impression that by adding a few of those methods to (After all, if you think about it, Path::components() is quite a weird API. It's an iterator that produces elements of which a certain variant can only ever appear as the first item, even though the signature/types would allow for something invalid like a Prefix to appear in the middle. If designed from scratch today, I wonder if we'd go for |
@m-ou-se I agree, it should be deprecated. The problem is that Path internally also uses |
We absolutely should come up with a solid list of these usages, and figure out how to design a path API that is designed to actually handle these use cases solidly, instead of just providing a bunch of lower level access and expecting people to solve basic problems every time. |
Path::components
is incorrect on Redox. I would like to develop the solutionhere: #51537.
The following is a description of the problem.
Suppose you have the following path:
file:/home/user/foo/bar.txt
You split the path into components using
Path::components
In Linux, this would be equivalent to the following:
Joining the components with the current directory would give you a path such as
this:
./file:/home/user/foo/bar.txt
In Redox, we want to be able to get from the original path to components back to
the original path without any modifications. Here are examples of this usage of
Path::components
:https://github.com/uutils/coreutils/search?q=components
In Redox, we have the following options for the
file:
component:Component::Normal("file:")
Component::Normal("file:")
followed byComponent::RootDir
Component::Prefix(Prefix::Verbatim("file:"))
Component::Prefix(Prefix::Scheme("file:"))
Option 1
Component::Normal("file:")
The path mentioned above would end up being the following after being rebuilt
from its components:
./file:/home/user/foo/bar.txt
This is the old way of doing things. It not only makes
Path::components
useless on Redox. Canonicalizing a path will always add a scheme like
file:
to the beginning, so it is likely that path handling will be incorrect.
Absolute paths would always be interpreted as relative.
❌ This option is unusable for Redox.
Option 2
Component::Normal("file:")
followed byComponent::RootDir
This would preserve the original meaning of the path, such that it could be
rebuilt from its components as follows:
file:/home/user/foo/bar.txt
However, this may require a large amount of work to handle, as it seems likely
that code exists that only checks the first component for being
Component::RootDir
orComponent::Prefix
in order to identify an absolutepath.
The documentation for
Prefix
provides one such example, which has likelyinspired similar usage:
https://doc.rust-lang.org/std/path/enum.Prefix.html#examples
❌ This option would likely break the expectations of many consumers of the
Prefix
enum.Option 3
Component::Prefix(Prefix::Verbatim("file:"))
This option preserves the original meaning of the path, a rebuilt path would be
this:
file:/home/user/foo/bar.txt
This, however, is overloading a variant meant to be used on Windows, for a path
looking like this:
\\?\home\user\foo\bar.txt
This means different code will be needed when running on Redox to correctly
parse paths to components and turn components into paths.
✔️ This does leave the enum untouched, while allowing for the
correct parsing of paths on Redox. The only downside is a possible lack of
clarity due to overloading the meaning of the
Prefix::Verbatim
variant.Option 4
Component::Prefix(Prefix::Scheme("file:"))
This option also preserves the original meaning of the path, a rebuilt path
would be this:
file:/home/user/foo/bar.txt
This is the most clear option, having separate code to handle specifically the
Redox scheme abstraction.
This has the downside of changing a stable enum,
Prefix
. There is, however,the possibility of having the extra enum variant be
#[cfg(target_os = "redox")]
, so as to preserve thePrefix
enum on otherplatforms.
✔️ This option could be used to have correct path parsing
without affecting the stability of the
Prefix
enum on non-Redox platforms,if a
cfg
attribute is used.Conclusion
Potentially the
Prefix
enum would be done different after a major version bump,perhaps using extension traits that are platform specific. I would think that
there would be an opaque
Prefix
struct, and something like.into_os_prefix()
would provide you with an os-specific enum to match against.
For the time being, options 3 and 4 seem to be possible, with some caveats, and
would allow code using stable Rust to quickly do-the-right-thing on Redox.
The text was updated successfully, but these errors were encountered: