aboutsummaryrefslogtreecommitdiff
path: root/mingling/src/res/dirs
diff options
context:
space:
mode:
Diffstat (limited to 'mingling/src/res/dirs')
-rw-r--r--mingling/src/res/dirs/current_dir.rs82
-rw-r--r--mingling/src/res/dirs/current_exe.rs81
-rw-r--r--mingling/src/res/dirs/home_dir.rs96
-rw-r--r--mingling/src/res/dirs/temp_dir.rs77
4 files changed, 336 insertions, 0 deletions
diff --git a/mingling/src/res/dirs/current_dir.rs b/mingling/src/res/dirs/current_dir.rs
new file mode 100644
index 0000000..1de84e0
--- /dev/null
+++ b/mingling/src/res/dirs/current_dir.rs
@@ -0,0 +1,82 @@
+use std::{
+ env::current_dir,
+ path::{Path, PathBuf},
+};
+
+/// A global resource for the Mingling library that provides the current working directory.
+///
+/// This struct wraps a `PathBuf` representing the current working directory at the time of
+/// creation. It is used as a shared resource in the Mingling framework so that multiple
+/// components can access the same base directory without repeatedly querying the OS.
+///
+/// # Default behavior
+///
+/// The `Default` implementation calls `std::env::current_dir().unwrap()` internally, which will
+/// **panic** if the current directory cannot be determined (e.g., if it has been deleted). If
+/// you want to handle this error gracefully, use [`ResCurrentDir::new`] instead, which returns
+/// a `Result`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ResCurrentDir {
+ cwd: PathBuf
+}
+
+impl ResCurrentDir {
+ /// Creates a new `ResCurrentDir` by querying the OS for the current working directory.
+ ///
+ /// Returns `Err` if the current directory cannot be determined (e.g., the directory has been
+ /// deleted or permissions are insufficient). Unlike the `Default` implementation, this
+ /// method does not panic on failure.
+ pub fn new() -> Result<Self, std::io::Error> {
+ Ok(Self { cwd: current_dir()? })
+ }
+}
+
+impl Default for ResCurrentDir {
+ fn default() -> Self {
+ Self { cwd: current_dir().unwrap() }
+ }
+}
+
+impl From<PathBuf> for ResCurrentDir {
+ fn from(path: PathBuf) -> Self {
+ Self { cwd: path }
+ }
+}
+
+impl From<&Path> for ResCurrentDir {
+ fn from(path: &Path) -> Self {
+ Self { cwd: path.to_path_buf() }
+ }
+}
+
+impl From<&PathBuf> for ResCurrentDir {
+ fn from(path: &PathBuf) -> Self {
+ Self { cwd: path.clone() }
+ }
+}
+
+impl From<ResCurrentDir> for PathBuf {
+ fn from(res: ResCurrentDir) -> Self {
+ res.cwd
+ }
+}
+
+impl AsRef<Path> for ResCurrentDir {
+ fn as_ref(&self) -> &Path {
+ self.cwd.as_path()
+ }
+}
+
+impl std::ops::Deref for ResCurrentDir {
+ type Target = PathBuf;
+
+ fn deref(&self) -> &Self::Target {
+ &self.cwd
+ }
+}
+
+impl std::ops::DerefMut for ResCurrentDir {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.cwd
+ }
+}
diff --git a/mingling/src/res/dirs/current_exe.rs b/mingling/src/res/dirs/current_exe.rs
new file mode 100644
index 0000000..051fcee
--- /dev/null
+++ b/mingling/src/res/dirs/current_exe.rs
@@ -0,0 +1,81 @@
+use std::{
+ env::current_exe,
+ path::{Path, PathBuf},
+};
+
+/// A global resource that provides the path of the current executable.
+///
+/// This struct wraps a `PathBuf` representing the full filesystem path of the
+/// currently running executable at the time of creation.
+///
+/// # Default behavior
+///
+/// The `Default` implementation calls `std::env::current_exe().unwrap()` internally,
+/// which will **panic** if the executable path cannot be determined (e.g., if the
+/// `/proc` filesystem is not available). If you want to handle this error gracefully,
+/// use [`ResCurrentExe::new`] instead, which returns a `Result`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ResCurrentExe {
+ exe: PathBuf,
+}
+
+impl ResCurrentExe {
+ /// Creates a new `ResCurrentExe` by querying the OS for the current executable path.
+ ///
+ /// Returns `Err` if the executable path cannot be determined (e.g., the `/proc`
+ /// filesystem is not available on Linux, or the process handle is invalid).
+ /// Unlike the `Default` implementation, this method does not panic on failure.
+ pub fn new() -> Result<Self, std::io::Error> {
+ Ok(Self { exe: current_exe()? })
+ }
+}
+
+impl Default for ResCurrentExe {
+ fn default() -> Self {
+ Self { exe: current_exe().unwrap() }
+ }
+}
+
+impl From<PathBuf> for ResCurrentExe {
+ fn from(path: PathBuf) -> Self {
+ Self { exe: path }
+ }
+}
+
+impl From<&Path> for ResCurrentExe {
+ fn from(path: &Path) -> Self {
+ Self { exe: path.to_path_buf() }
+ }
+}
+
+impl From<&PathBuf> for ResCurrentExe {
+ fn from(path: &PathBuf) -> Self {
+ Self { exe: path.clone() }
+ }
+}
+
+impl From<ResCurrentExe> for PathBuf {
+ fn from(res: ResCurrentExe) -> Self {
+ res.exe
+ }
+}
+
+impl AsRef<Path> for ResCurrentExe {
+ fn as_ref(&self) -> &Path {
+ self.exe.as_path()
+ }
+}
+
+impl std::ops::Deref for ResCurrentExe {
+ type Target = PathBuf;
+
+ fn deref(&self) -> &Self::Target {
+ &self.exe
+ }
+}
+
+impl std::ops::DerefMut for ResCurrentExe {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.exe
+ }
+}
diff --git a/mingling/src/res/dirs/home_dir.rs b/mingling/src/res/dirs/home_dir.rs
new file mode 100644
index 0000000..de2e5e7
--- /dev/null
+++ b/mingling/src/res/dirs/home_dir.rs
@@ -0,0 +1,96 @@
+use std::path::{Path, PathBuf};
+
+/// A global resource that provides the current user's home directory path.
+///
+/// This struct wraps a `PathBuf` representing the user's home directory.
+///
+/// **Platform notes:**
+/// - On **Unix**: reads the `HOME` environment variable.
+/// - On **Windows**: reads the `USERPROFILE` environment variable.
+///
+/// # Default behavior
+///
+/// The `Default` implementation calls [`ResHomeDir::new`] and **panics** if the home
+/// directory cannot be determined (e.g., the relevant environment variable is not set).
+/// Use [`ResHomeDir::new`] to handle this error gracefully.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ResHomeDir {
+ home: PathBuf,
+}
+
+impl ResHomeDir {
+ /// Creates a new `ResHomeDir` by querying the environment for the user's home directory.
+ ///
+ /// Returns `Err` if the home directory cannot be determined (e.g., the `HOME` or
+ /// `USERPROFILE` environment variable is not set).
+ pub fn new() -> Result<Self, std::io::Error> {
+ let home = home_dir_env()
+ .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "home directory not found"))?;
+ Ok(Self { home })
+ }
+}
+
+impl Default for ResHomeDir {
+ fn default() -> Self {
+ Self { home: home_dir_env().expect("home directory not found") }
+ }
+}
+
+impl From<PathBuf> for ResHomeDir {
+ fn from(path: PathBuf) -> Self {
+ Self { home: path }
+ }
+}
+
+impl From<&Path> for ResHomeDir {
+ fn from(path: &Path) -> Self {
+ Self { home: path.to_path_buf() }
+ }
+}
+
+impl From<&PathBuf> for ResHomeDir {
+ fn from(path: &PathBuf) -> Self {
+ Self { home: path.clone() }
+ }
+}
+
+impl From<ResHomeDir> for PathBuf {
+ fn from(res: ResHomeDir) -> Self {
+ res.home
+ }
+}
+
+impl AsRef<Path> for ResHomeDir {
+ fn as_ref(&self) -> &Path {
+ self.home.as_path()
+ }
+}
+
+impl std::ops::Deref for ResHomeDir {
+ type Target = PathBuf;
+
+ fn deref(&self) -> &Self::Target {
+ &self.home
+ }
+}
+
+impl std::ops::DerefMut for ResHomeDir {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.home
+ }
+}
+
+/// Returns the user's home directory by checking platform-specific environment variables.
+///
+/// - Unix: `$HOME`
+/// - Windows: `%USERPROFILE%`
+fn home_dir_env() -> Option<PathBuf> {
+ #[cfg(target_os = "windows")]
+ {
+ std::env::var_os("USERPROFILE").map(PathBuf::from)
+ }
+ #[cfg(not(target_os = "windows"))]
+ {
+ std::env::var_os("HOME").map(PathBuf::from)
+ }
+}
diff --git a/mingling/src/res/dirs/temp_dir.rs b/mingling/src/res/dirs/temp_dir.rs
new file mode 100644
index 0000000..f4f0dca
--- /dev/null
+++ b/mingling/src/res/dirs/temp_dir.rs
@@ -0,0 +1,77 @@
+use std::{
+ env::temp_dir,
+ path::{Path, PathBuf},
+};
+
+/// A global resource that provides the system temporary directory path.
+///
+/// This struct wraps a `PathBuf` representing the platform's temporary directory
+/// (e.g., `/tmp` on Unix, `%TEMP%` on Windows).
+///
+/// Note that `std::env::temp_dir()` is infallible — it always returns a path,
+/// falling back to a platform-specific default (e.g., `/tmp` on Unix) if the
+/// environment variable is not set.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ResTempDir {
+ tmp: PathBuf,
+}
+
+impl ResTempDir {
+ /// Creates a new `ResTempDir` by querying the OS for the system temporary directory.
+ ///
+ /// This method is infallible since `std::env::temp_dir()` always succeeds,
+ /// returning a platform-specific default when environment variables are unset.
+ pub fn new() -> Self {
+ Self { tmp: temp_dir() }
+ }
+}
+
+impl Default for ResTempDir {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl From<PathBuf> for ResTempDir {
+ fn from(path: PathBuf) -> Self {
+ Self { tmp: path }
+ }
+}
+
+impl From<&Path> for ResTempDir {
+ fn from(path: &Path) -> Self {
+ Self { tmp: path.to_path_buf() }
+ }
+}
+
+impl From<&PathBuf> for ResTempDir {
+ fn from(path: &PathBuf) -> Self {
+ Self { tmp: path.clone() }
+ }
+}
+
+impl From<ResTempDir> for PathBuf {
+ fn from(res: ResTempDir) -> Self {
+ res.tmp
+ }
+}
+
+impl AsRef<Path> for ResTempDir {
+ fn as_ref(&self) -> &Path {
+ self.tmp.as_path()
+ }
+}
+
+impl std::ops::Deref for ResTempDir {
+ type Target = PathBuf;
+
+ fn deref(&self) -> &Self::Target {
+ &self.tmp
+ }
+}
+
+impl std::ops::DerefMut for ResTempDir {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.tmp
+ }
+}