vexide_core/
path.rs

1//! Path manipulation.
2//!
3//! This module provides the [`Path`] type for working with VEXos filesystem paths
4//! abstractly. Paths are case sensitive.
5
6use alloc::string::String;
7use core::{borrow::Borrow, ops::Deref};
8
9use crate::fs::{FsStr, FsString};
10
11/// A slice of a path (akin to [`str`]).
12///
13/// More details about the overall approach can be found in the [module documentation](self).
14#[repr(transparent)]
15#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct Path {
17    pub(crate) inner: FsStr,
18}
19
20impl Path {
21    /// Directly wraps a string slice as a `Path` slice.
22    ///
23    /// This is a cost-free conversion.
24    ///
25    /// # Examples
26    ///
27    /// ```
28    /// use vexide::path::Path;
29    ///
30    /// Path::new("foo.txt");
31    /// ```
32    ///
33    /// You can create `Path`s from `String`s, or even other `Path`s:
34    ///
35    /// ```
36    /// use alloc::string::String;
37    /// use vexide::path::Path;
38    ///
39    /// let string = String::from("foo.txt");
40    /// let from_string = Path::new(&string);
41    /// let from_path = Path::new(&from_string);
42    /// assert_eq!(from_string, from_path);
43    /// ```
44    pub fn new<'a, P: AsRef<FsStr> + 'a>(path: P) -> &'a Self {
45        unsafe { &*(core::ptr::from_ref::<FsStr>(path.as_ref()) as *const Path) }
46    }
47
48    /// Yields the underlying [`FsStr`] slice.
49    ///
50    /// # Examples
51    ///
52    /// ```
53    /// use vexide::{path::Path, fs::FsStr};
54    ///
55    /// let fs_str = Path::new("foo.txt").as_os_str();
56    /// assert_eq!(os_str, FsStr::new("foo.txt"));
57    /// ```
58    #[must_use]
59    pub const fn as_fs_str(&self) -> &FsStr {
60        &self.inner
61    }
62}
63impl AsRef<Path> for Path {
64    fn as_ref(&self) -> &Path {
65        self
66    }
67}
68impl AsRef<Path> for &str {
69    fn as_ref(&self) -> &Path {
70        Path::new(self)
71    }
72}
73
74/// An owned, mutable path (akin to `String`).
75///
76/// This type implements `Deref` to [`Path`],
77/// menaing all methods on a [`Path`] can be used on a [`PathBuf`].
78#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
79pub struct PathBuf {
80    inner: FsString,
81}
82//TODO: reimplement std's funcs
83impl PathBuf {
84    /// Allocates a new, empty, path.
85    #[must_use]
86    pub const fn new() -> Self {
87        Self {
88            inner: FsString::new(),
89        }
90    }
91
92    fn as_path(&self) -> &Path {
93        Path::new(self.inner.as_fs_str())
94    }
95}
96
97impl From<String> for PathBuf {
98    fn from(value: String) -> Self {
99        Self {
100            inner: FsString::from(value),
101        }
102    }
103}
104impl Deref for PathBuf {
105    type Target = Path;
106
107    fn deref(&self) -> &Path {
108        self.as_path()
109    }
110}
111
112impl Borrow<Path> for PathBuf {
113    fn borrow(&self) -> &Path {
114        self.as_path()
115    }
116}
117impl AsRef<Path> for PathBuf {
118    fn as_ref(&self) -> &Path {
119        self.as_path()
120    }
121}