anyhow_std/
osstr.rs

1use anyhow::Context;
2use std::borrow::Cow;
3use std::ffi::OsStr;
4
5const LONG_STRING_DISPLAY_LIMIT: usize = 80;
6
7/// Extend [std::ffi::OsStr] with [anyhow] methods
8pub trait OsStrAnyhow {
9    /// Produce a utf8 `&str` or provide an error describing the string, truncated if long
10    fn to_str_anyhow(&self) -> anyhow::Result<&str>;
11}
12
13impl OsStrAnyhow for OsStr {
14    fn to_str_anyhow(&self) -> anyhow::Result<&str> {
15        self.to_str()
16            .ok_or_else(|| anyhow::Error::msg("not valid utf8"))
17            .with_context(|| {
18                format!(
19                    "while processing os string {:?}",
20                    truncate_long_strings(self.to_string_lossy())
21                )
22            })
23    }
24}
25
26fn truncate_long_strings(s: Cow<'_, str>) -> Cow<'_, str> {
27    let sref = s.as_ref();
28    let charcnt = sref.chars().count();
29
30    if charcnt <= LONG_STRING_DISPLAY_LIMIT {
31        s
32    } else {
33        const HALF: usize = LONG_STRING_DISPLAY_LIMIT / 2;
34
35        dbg!(Cow::from(format!(
36            "{}\u{2772}\u{2026}\u{2773}{}",
37            sref.chars().take(HALF).collect::<String>(),
38            sref.chars().skip(charcnt - HALF + 3).collect::<String>(),
39        )))
40    }
41}
42
43#[cfg(test)]
44mod tests;