Rust Path Components
Path components are the pieces of a path, in order. components() hands out every piece one by one.
See the pieces
Print each component with {:?} to see its kind:
for piece in Path::new("reports/2026").components() {
println!("{piece:?}");
}The special pieces
A leading / is RootDir. A .. piece stays a ParentDir. Components never merge or resolve them:
for piece in Path::new("/a/b/../c").components() {
println!("{piece:?}");
}Match on the kind
A match sorts the pieces into kinds. Count only the real names:
let mut names = 0;
for piece in Path::new("/a/b/../c").components() {
if let Component::Normal(_) = piece {
names += 1;
}
}
println!("names = {names}");Walk up with ancestors
ancestors() starts at the full path. It ends at the empty path:
for up in Path::new("reports/2026/sales.txt").ancestors() {
println!("[{}]", up.display());
}Test a prefix by pieces
starts_with compares whole pieces. A shared spelling is not enough:
println!("{}", Path::new("reports/2026/x.txt").starts_with("reports/2026"));
println!("{}", Path::new("reports2/x.txt").starts_with("reports"));Example
use std::path::{Component, Path};
fn main() {
let path = Path::new("/home/ferris/docs/../notes.txt");
println!("pieces = {}", path.components().count());
for piece in path.components() {
match piece {
Component::RootDir => println!("root"),
Component::ParentDir => println!(".."),
Component::Normal(name) => println!("{}", name.to_string_lossy()),
_ => {}
}
}
}Key points
- Use path.components() to walk the pieces of a path in order: each piece is a Component
- Component::Normal(name) is an ordinary folder or file name: it is held as an &OsStr
- Component::RootDir is the leading / of an absolute path: Component::ParentDir is a .. piece
- Use path.ancestors() to get the path itself, then its parent, then each grandparent: the last one is the empty path
- Use path.starts_with(base) to test a whole-piece prefix: reports2 does not start with reports
- Path components are the ordered pieces that a path is made of.
- file_name() and parent() take a path apart in bigger chunks.
- But ./a does not equal a.
In this example, the path holds six components. The match gives each kind its own print line. RootDir prints as the word root. Each Normal piece prints its name. The ParentDir piece prints as two dots. Nothing resolves the .. away. Components report the path as written. Resolving is a different job, and the Rust Real Paths lesson covers it.
Note
Path equality compares pieces, not text.
a/./b equals a/b.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
What is the first component of the path /a/b?