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

PrefixComponent cannot be constructed in any way #83578

Open
Boscop opened this issue Mar 27, 2021 · 1 comment
Open

PrefixComponent cannot be constructed in any way #83578

Boscop opened this issue Mar 27, 2021 · 1 comment
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@Boscop
Copy link

Boscop commented Mar 27, 2021

I need to pass a canonicalized path to cl.exe:
https://github.com/google/autocxx/blob/78965991ba04e6c9383920e9c4275deaa808a7a5/demo/build.rs#L19

Path::canonicalize returns \\?\C:\foo\bar instead of C:\foo\bar, which cl.exe doesn't interpret correctly (it's as if I hadn't passed that include path).
So I need to strip the prefix. It seems the way to do it, is like this:

let path = PathBuf::from("src")
    .canonicalize()
    .unwrap()
    .components()
    .map(|c| match c {
        Component::Prefix(p) => Component::Prefix(match p.kind() {
            Prefix::VerbatimDisk(p) => Prefix::Disk(p),
            Prefix::VerbatimUNC(a, b) => Prefix::UNC(a, b),
            p => p,
        }),
        c => c,
    })
    .collect::<PathBuf>();

But I need to map a PrefixComponent to a PrefixComponent, and there is no public constructor for it!
https://doc.rust-lang.org/stable/std/path/struct.PrefixComponent.html

So this code doesn't work:
image

Can you please add a constructor for it?
And maybe also a method to canonicalize a Path without adding such a prefix?

@Boscop Boscop added the C-bug Category: This is a bug. label Mar 27, 2021
@dylni
Copy link
Contributor

dylni commented Mar 27, 2021

I've worked a little with these structs, so I might be able to answer why they're designed this way.

But I need to map a PrefixComponent to a PrefixComponent, and there is no public constructor for it!

The issue is that libstd doesn't have any way to convert Prefix to Path. If you give Prefix::Disk, it doesn't know what path you want to use for that prefix. For example, Prefix::Disk always has a lowercase disk letter when you extract it from PrefixComponent. However, converting PrefixComponent to Path will always use the original case.

And maybe also a method to canonicalize a Path without adding such a prefix?

Removing \\?\ can be difficult for some paths on Windows, so the issue you're looking for is probably #59117. Although no solution exists in libstd, I created normpath, which was mentioned on that issue and might help.

@fmease fmease added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. C-feature-request Category: A feature request, i.e: not implemented / a PR. A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` and removed C-bug Category: This is a bug. needs-triage-legacy labels Jan 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-io Area: `std::io`, `std::fs`, `std::net` and `std::path` C-feature-request Category: A feature request, i.e: not implemented / a PR. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants