evobench_tools/serde_types/
tilde_path.rs1use std::{
2 path::{Path, PathBuf},
3 str::FromStr,
4};
5
6use anyhow::Result;
7use serde::de::Visitor;
8
9use crate::utillib::path_resolve_home::path_resolve_home;
10
11#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
14pub struct TildePath<P: AsRef<Path>>(P);
15
16impl<P: AsRef<Path>> TildePath<P> {
17 pub fn resolve(&self) -> Result<PathBuf> {
21 path_resolve_home(self.0.as_ref())
22 }
23}
24
25impl FromStr for TildePath<PathBuf> {
26 type Err = core::convert::Infallible;
27
28 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
29 Ok(Self(PathBuf::from_str(s)?))
30 }
31}
32
33struct OurVisitor;
34impl<'de> Visitor<'de> for OurVisitor {
35 type Value = TildePath<PathBuf>;
36
37 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
38 formatter.write_str("anything, this is infallible")
39 }
40
41 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
42 where
43 E: serde::de::Error,
44 {
45 v.parse().map_err(E::custom)
46 }
47}
48
49impl<'de> serde::Deserialize<'de> for TildePath<PathBuf> {
50 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
51 deserializer.deserialize_str(OurVisitor)
52 }
53}
54
55impl serde::Serialize for TildePath<PathBuf> {
56 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
57 where
58 S: serde::Serializer,
59 {
60 if let Some(s) = self.0.to_str() {
61 serializer.serialize_str(s)
62 } else {
63 Err(serde::ser::Error::custom("path contains invalid UTF-8"))
64 }
65 }
66}