Home > Software design >  How to get drive letter returned as a string?
How to get drive letter returned as a string?

Time:01-13

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:
  • Related