parallel_disk_usage/
os_string_display.rs

1use derive_more::{AsMut, AsRef, Deref, DerefMut, From, FromStr};
2use std::{
3    ffi::{OsStr, OsString},
4    fmt::{Debug, Display, Error, Formatter},
5};
6
7#[cfg(feature = "json")]
8use serde::{Deserialize, Serialize};
9
10/// [`Display`] inner [`OsStr`] or [`OsString`].
11///
12/// If the inner string can be converted to UTF-8, displays the UTF-8.
13/// Otherwise, displays its [`Debug`] form.
14#[derive(
15    Debug,
16    Default,
17    Clone,
18    Copy,
19    PartialEq,
20    Eq,
21    PartialOrd,
22    Ord,
23    AsMut,
24    AsRef,
25    Deref,
26    DerefMut,
27    From,
28    FromStr,
29)]
30#[cfg_attr(feature = "json", derive(Deserialize, Serialize))]
31pub struct OsStringDisplay<Inner = OsString>(pub Inner)
32where
33    Inner: AsRef<OsStr> + Debug;
34
35impl<Inner> OsStringDisplay<Inner>
36where
37    Inner: AsRef<OsStr> + Debug,
38{
39    /// Get immutable reference to the inner value.
40    #[inline]
41    pub fn inner(&self) -> &Inner {
42        &self.0
43    }
44
45    /// Get immutable reference to the inner `OsStr`.
46    #[inline]
47    pub fn as_os_str(&self) -> &OsStr {
48        self.inner().as_ref()
49    }
50}
51
52impl OsStringDisplay {
53    /// Create an [`OsStringDisplay`] of [`OsString`].
54    #[inline]
55    pub fn os_string_from(source: impl Into<OsString>) -> Self {
56        source.into().into()
57    }
58}
59
60impl<Inner> AsRef<OsStr> for OsStringDisplay<Inner>
61where
62    Inner: AsRef<OsStr> + Debug,
63{
64    fn as_ref(&self) -> &OsStr {
65        self.as_os_str()
66    }
67}
68
69impl<Inner> Display for OsStringDisplay<Inner>
70where
71    Inner: AsRef<OsStr> + Debug,
72{
73    fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error> {
74        let inner = self.as_os_str();
75        if let Some(utf8) = inner.to_str() {
76            write!(formatter, "{utf8}")
77        } else {
78            write!(formatter, "{inner:?}")
79        }
80    }
81}