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}