v_utils 2.15.41

My utils crate
Documentation
use std::{
	path::{Path, PathBuf},
	str::FromStr,
};

use eyre::{Error, Result};
use serde::{Deserialize, Deserializer, Serialize, de};

#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, derive_new::new)]
pub struct ExpandedPath(pub PathBuf);
impl ExpandedPath {
	pub fn inner(self) -> PathBuf {
		self.0
	}

	pub fn display(&self) -> std::path::Display<'_> {
		self.0.display()
	}

	pub fn parent(&self) -> Option<ExpandedPath> {
		self.0.parent().map(|p| ExpandedPath(p.to_path_buf()))
	}

	pub fn join<P: AsRef<Path>>(&self, path: P) -> ExpandedPath {
		ExpandedPath(self.0.join(path))
	}
}

impl<'de> Deserialize<'de> for ExpandedPath {
	fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
	where
		D: Deserializer<'de>, {
		let s = String::deserialize(deserializer)?;
		FromStr::from_str(&s).map_err(de::Error::custom)
	}
}
impl FromStr for ExpandedPath {
	type Err = eyre::Report;

	fn from_str(s: &str) -> Result<Self> {
		let path_buf = match s.starts_with("~") {
			true => {
				let home_dir = dirs::home_dir().ok_or_else(|| Error::msg("Failed to determine user's home directory"))?;

				match s.len() {
					l if l < 2 => Ok(home_dir),
					l if l > 2 => Ok(home_dir.join(&s[2..])),
					_ => Err(Error::msg("Incorrect Path")),
				}
			}
			false => Ok(PathBuf::from(s)),
		}?;

		Ok(ExpandedPath(path_buf))
	}
}

impl From<&str> for ExpandedPath {
	fn from(s: &str) -> Self {
		ExpandedPath::from_str(s).unwrap()
	}
}
impl From<String> for ExpandedPath {
	fn from(s: String) -> Self {
		ExpandedPath::from_str(&s).unwrap()
	}
}
impl From<PathBuf> for ExpandedPath {
	fn from(p: PathBuf) -> Self {
		ExpandedPath(p)
	}
}

impl std::fmt::Display for ExpandedPath {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		self.0.display().fmt(f)
	}
}
impl AsRef<Path> for ExpandedPath {
	fn as_ref(&self) -> &Path {
		self.0.as_ref()
	}
}
impl std::ops::Deref for ExpandedPath {
	type Target = PathBuf;

	fn deref(&self) -> &Self::Target {
		&self.0
	}
}