use std::path::{Component, Path};
use crate::error::bound_message;
pub(crate) fn short_path(path: &Path) -> String {
let mut tail: Vec<String> = path
.components()
.rev()
.filter_map(|c| match c {
Component::Normal(s) => Some(s.to_string_lossy().into_owned()),
Component::Prefix(_) | Component::RootDir | Component::CurDir | Component::ParentDir => None,
})
.take(3)
.collect();
if tail.is_empty() {
return "<unknown>".to_owned();
}
tail.reverse();
let mut joined = tail.join("/");
if joined.len() > crate::LEAN_ERROR_MESSAGE_LIMIT {
joined = bound_message(joined);
}
joined
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn short_path_keeps_three_tail_components() {
assert_eq!(
short_path(Path::new("/Users/me/lake/build/lib/lib.dylib")),
"build/lib/lib.dylib",
);
}
#[test]
fn short_path_handles_short_input() {
assert_eq!(short_path(Path::new("lib.dylib")), "lib.dylib");
assert_eq!(short_path(Path::new("/tmp/lib.dylib")), "tmp/lib.dylib");
}
#[test]
fn short_path_empty_path_falls_back_to_placeholder() {
assert_eq!(short_path(Path::new("")), "<unknown>");
}
}