magicpak/domain/
bundle_path.rs

1use std::borrow::{Borrow, Cow};
2use std::ffi::{OsStr, OsString};
3use std::fmt;
4use std::ops::Deref;
5use std::path::{Path, PathBuf};
6
7pub struct BundlePath {
8    inner: OsStr,
9}
10
11impl BundlePath {
12    pub fn new<S>(s: &S) -> &BundlePath
13    where
14        S: AsRef<OsStr> + ?Sized,
15    {
16        unsafe { &*(s.as_ref() as *const OsStr as *const BundlePath) }
17    }
18
19    pub fn projection<'a, P>(p: &'a P) -> &'a BundlePath
20    where
21        P: AsRef<Path> + 'a,
22    {
23        let path = p.as_ref().strip_prefix("/").unwrap_or_else(|_| p.as_ref());
24        BundlePath::new(path)
25    }
26
27    pub fn to_path_buf(&self) -> BundlePathBuf {
28        BundlePathBuf {
29            inner: self.inner.to_os_string(),
30        }
31    }
32
33    pub fn to_str_lossy(&self) -> Cow<str> {
34        self.inner.to_string_lossy()
35    }
36
37    pub fn display(&self) -> Display<'_> {
38        Display { inner: self }
39    }
40
41    pub fn reify<P>(&self, dist: P) -> PathBuf
42    where
43        P: AsRef<Path>,
44    {
45        dist.as_ref().join(&self.inner)
46    }
47}
48
49impl ToOwned for BundlePath {
50    type Owned = BundlePathBuf;
51
52    fn to_owned(&self) -> BundlePathBuf {
53        self.to_path_buf()
54    }
55}
56
57impl AsRef<BundlePath> for BundlePath {
58    fn as_ref(&self) -> &BundlePath {
59        self
60    }
61}
62
63#[derive(PartialEq, Eq, Hash, Clone)]
64pub struct BundlePathBuf {
65    inner: OsString,
66}
67
68impl Deref for BundlePathBuf {
69    type Target = BundlePath;
70
71    fn deref(&self) -> &BundlePath {
72        BundlePath::new(&self.inner)
73    }
74}
75
76impl AsRef<BundlePath> for BundlePathBuf {
77    fn as_ref(&self) -> &BundlePath {
78        self
79    }
80}
81
82impl Borrow<BundlePath> for BundlePathBuf {
83    fn borrow(&self) -> &BundlePath {
84        self.deref()
85    }
86}
87
88pub struct Display<'a> {
89    inner: &'a BundlePath,
90}
91
92impl<'a> fmt::Display for Display<'a> {
93    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94        write!(f, "[{}]", Path::new(&self.inner.inner).display())
95    }
96}