I'm struggling to get a string of the prefix of a path. All I want to do is get the "D:"
from the string "D:\Household\Internet\September_2022_Statement.pdf"
.
If I follow the example for std:path:Component
in here, I can see the value I want but don't know how to get to it.
The code I am running is:
let filepath = "D:\\Household\\Internet\\September_2022_Statement.pdf";
let path = Path::new(filepath);
let components = path.components().collect::<Vec<_>>();
for value in &components {
println!("{:?}", value);
}
The output I get is:
Prefix(PrefixComponent { raw: "D:", parsed: Disk(68) })
RootDir
Normal("Household")
Normal("Internet")
Normal("September_2022_Statement.pdf")
How do I get the raw value "D:"
from Prefix(PrefixComponent { raw: "D:", parsed: Disk(68) })
?
CodePudding user response:
Looks like components is an iterator of instances of the Component
enum, which is declared as
pub enum Component<'a> {
Prefix(PrefixComponent<'a>),
RootDir,
CurDir,
ParentDir,
Normal(&'a OsStr),
}
Since you know that the drive is a Prefix
, you can test for that.
let filepath = "D:\\Household\\Internet\\September_2022_Statement.pdf";
let path = Path::new(filepath);
let components = path.components().collect::<Vec<_>>();
for value in &components {
if let std::path::Component::Prefix(prefixComponent) = value {
return Some(value.as_os_str());
// instead of returning you could set this to a mutable variable
// or you could just check the first element of `components`
}
}
None // if this were a function that returned Option<String>
The example from the Rust docs is
use std::path::{Component, Path, Prefix};
use std::ffi::OsStr;
let path = Path::new(r"c:\you\later\");
match path.components().next().unwrap() {
Component::Prefix(prefix_component) => {
assert_eq!(Prefix::Disk(b'C'), prefix_component.kind());
assert_eq!(OsStr::new("c:"), prefix_component.as_os_str());
}
_ => unreachable!(),
}
CodePudding user response:
Thanks to @Samathingamajig and @PitaJ, I was able to achieve what I needed. Obviously, I am a Rust newbie so I'm sure there is a cleaner way of doing this, but combining the help suggested, this works for me:
let filepath = "D:\\Household\\Internet\\September_2022_Statement.pdf";
let path = Path::new(fileName);
let components = path.components().collect::<Vec<_>>();
let mut os_string = OsString::new();
match path.components().next().unwrap() {
Component::Prefix(prefix_component) => {
os_string = prefix_component.as_os_str().into();
}
_ => todo!()
}
println!("{}", os_string.to_str().unwrap());
Resulting output:
D: