Proposal
Problem statement
There is no way to check in const context if the target platform recognizes multiple path separators (and, if so, which secondary separator(s) are used).
Motivating examples or use cases
I'm currently working on a Path::is_normalized trait overlay, which would check if the (currently unstable) Path::normalize_lexically operation will change the input. One side effect of normalization is changing any secondary path separators to primary separators on platforms that recognize such, eg. Windows '/' becomes '\\'.
On platforms that do not support secondary separators (eg. Unix), that entire check could be excluded by the compiler. However, while the primary path separator can be accessed using std::path::MAIN_SEPARATOR, there is no way to identify (the presence of) secondary separators in const context. std::path::is_separator can be used to imply the presence of multiple separators, but it is not currently const.
Solution sketch
- make
std::path::is_separator const
- add
std::path::SEPARATORS and std::path::SEPARATORS_STR:
// currently present:
pub const MAIN_SEPARATOR: char = '\\';
pub const MAIN_SEPARATOR_STR: &str = "\\";
// add:
pub const SEPARATORS: &[char] = &['\\', '/'];
pub const SEPARATORS_STR: &[&str] = &["\\", "/"];
Alternatives
There are currently no platforms that recognize more than two separators, so Option could be used:
pub const ALT_SEPARATOR: Option<char> = Some('/');
pub const ALT_SEPARATOR_STR: Option<&str> = Some("/");
Or the MAIN_SEPARATOR and list could be structured to not overlap:
pub const ALT_SEPARATORS: &[char] = &['/'];
pub const ALT_SEPARATORS_STR: &[&str] = &["/"];
I favour the SEPARATORS solution above because it enables a one-step check SEPARATORS.contains(c) rather than multi-step c == MAIN_SEPARATOR || ALT_SEPARATOR.is_some_and(|alt_c| c == alt_c).
Alternatively, the barebones low-friction solution is to make is_separator const without adding another constant. This would provide the ability to surface the information at compile time, if roundaboutly:
// Probably fine as long as RISC OS (.) or Mac OS Classic (:) aren't added as targets
const HAS_MULTI_SEP: bool = is_separator('/') && is_separator('\\');
if HAS_MULTI_SEP {
// do check for separator mutation here
}
Links and related work
This is the current state of path separators in std::sys::path:
| Platform |
MAIN_SEPARATOR |
alt separator |
| Cygwin |
/ |
\ |
| Windows |
\ |
/ |
| Fortanix SGX |
/ |
|
| UEFI |
\ |
|
| Unix |
/ |
|
| SOLID ASP3 |
\ |
|
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.
Proposal
Problem statement
There is no way to check in const context if the target platform recognizes multiple path separators (and, if so, which secondary separator(s) are used).
Motivating examples or use cases
I'm currently working on a
Path::is_normalizedtrait overlay, which would check if the (currently unstable)Path::normalize_lexicallyoperation will change the input. One side effect of normalization is changing any secondary path separators to primary separators on platforms that recognize such, eg. Windows'/'becomes'\\'.On platforms that do not support secondary separators (eg. Unix), that entire check could be excluded by the compiler. However, while the primary path separator can be accessed using
std::path::MAIN_SEPARATOR, there is no way to identify (the presence of) secondary separators in const context.std::path::is_separatorcan be used to imply the presence of multiple separators, but it is not currentlyconst.Solution sketch
std::path::is_separatorconststd::path::SEPARATORSandstd::path::SEPARATORS_STR:Alternatives
There are currently no platforms that recognize more than two separators, so
Optioncould be used:Or the
MAIN_SEPARATORand list could be structured to not overlap:I favour the
SEPARATORSsolution above because it enables a one-step checkSEPARATORS.contains(c)rather than multi-stepc == MAIN_SEPARATOR || ALT_SEPARATOR.is_some_and(|alt_c| c == alt_c).Alternatively, the barebones low-friction solution is to make
is_separatorconst without adding another constant. This would provide the ability to surface the information at compile time, if roundaboutly:Links and related work
This is the current state of path separators in
std::sys::path:MAIN_SEPARATOR/\\//\/\What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution: