1
use std::borrow::Cow;
2
use std::ffi::OsStr;
3
use std::path::Path;
4

            
5
/// This has been adapted from cross-rs file.rs source
6
/// https://github.com/cross-rs/cross/blob/4090beca3cfffa44371a5bba524de3a578aa46c3/src/file.rs#L12
7
pub trait ToUtf8 {
8
  fn to_utf8(&self) -> anyhow::Result<&str>;
9
}
10

            
11
pub trait DisplayPath {
12
  fn display_lossy(&self) -> Cow<'_, str>;
13
}
14

            
15
/// Implement `ToUtf8` for `OsStr`
16
impl ToUtf8 for OsStr {
17
  /// Convert `OsStr` to `&str`
18
  /// This function will return an error if the conversion fails
19
206
  fn to_utf8(&self) -> anyhow::Result<&str> {
20
206
    self
21
206
      .to_str()
22
206
      .ok_or_else(|| anyhow::anyhow!("Unable to convert `{self:?}` to UTF-8 string"))
23
206
  }
24
}
25

            
26
impl DisplayPath for OsStr {
27
10
  fn display_lossy(&self) -> Cow<'_, str> {
28
10
    self.to_string_lossy()
29
10
  }
30
}
31

            
32
/// Implement `ToUtf8` for `Path`
33
impl ToUtf8 for Path {
34
  /// Convert `Path` to `&str`
35
204
  fn to_utf8(&self) -> anyhow::Result<&str> {
36
204
    self.as_os_str().to_utf8()
37
204
  }
38
}
39

            
40
impl DisplayPath for Path {
41
10
  fn display_lossy(&self) -> Cow<'_, str> {
42
10
    self.as_os_str().display_lossy()
43
10
  }
44
}
45

            
46
#[cfg(test)]
47
mod tests {
48
  use super::*;
49

            
50
  #[test]
51
2
  fn test_os_str_to_utf8() -> anyhow::Result<()> {
52
2
    let os_str = OsStr::new("hello");
53
2
    assert_eq!(os_str.to_utf8()?, "hello");
54
2
    Ok(())
55
2
  }
56

            
57
  #[test]
58
2
  fn test_path_to_utf8() -> anyhow::Result<()> {
59
2
    let path = Path::new("hello");
60
2
    assert_eq!(path.to_utf8()?, "hello");
61
2
    Ok(())
62
2
  }
63

            
64
  #[test]
65
2
  fn test_path_display_lossy() {
66
2
    let path = Path::new("hello");
67
2
    assert_eq!(path.display_lossy(), "hello");
68
2
  }
69
}