Skip to main content

tui_breadcrumb/
path.rs

1// ==============================================================================
2// Path Conversion Utilities
3// ==============================================================================
4
5//! Utilities to convert standard filesystem paths ([`Path`]) into breadcrumb items.
6
7use crate::item::BreadcrumbItem;
8use std::path::{Component, Path};
9
10/// Parses a filesystem [`Path`] into a vector of [`BreadcrumbItem`] segments.
11///
12/// Handles root directories (`/` on Unix, drive letters on Windows), normal folder/file components,
13/// and special dot segments (`.`, `..`).
14///
15/// # Examples
16///
17/// ```rust
18/// use std::path::Path;
19/// use tui_breadcrumb::from_path;
20///
21/// let path = Path::new("/var/log/nginx/access.log");
22/// let items = from_path(path);
23/// assert_eq!(items.len(), 5);
24/// ```
25#[must_use]
26pub fn from_path<P: AsRef<Path>>(path: P) -> Vec<BreadcrumbItem<'static>> {
27    let path = path.as_ref();
28    let mut items = Vec::new();
29
30    for component in path.components() {
31        match component {
32            Component::RootDir => {
33                items.push(BreadcrumbItem::new("/".to_string()));
34            }
35            Component::Prefix(prefix) => {
36                let s = prefix.as_os_str().to_string_lossy().to_string();
37                items.push(BreadcrumbItem::new(s));
38            }
39            Component::CurDir => {
40                items.push(BreadcrumbItem::new(".".to_string()));
41            }
42            Component::ParentDir => {
43                items.push(BreadcrumbItem::new("..".to_string()));
44            }
45            Component::Normal(os_str) => {
46                let s = os_str.to_string_lossy().to_string();
47                items.push(BreadcrumbItem::new(s));
48            }
49        }
50    }
51
52    items
53}
54
55#[cfg(test)]
56mod tests {
57    use super::*;
58
59    #[test]
60    fn test_from_path() {
61        let path = Path::new("/projects/ratatui/src/main.rs");
62        let items = from_path(path);
63        let labels: Vec<String> = items
64            .iter()
65            .map(|item| {
66                item.label
67                    .spans
68                    .iter()
69                    .map(|s| s.content.as_ref())
70                    .collect()
71            })
72            .collect();
73
74        assert_eq!(labels, vec!["/", "projects", "ratatui", "src", "main.rs"]);
75    }
76}