Most of the refactor. Need to switch machines.

This commit is contained in:
Olivia Brooks
2026-02-15 09:36:04 -05:00
parent dda863e512
commit e41d4bcd76
61 changed files with 3390 additions and 618 deletions

14
crates/path/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "path"
version = "0.1.0"
edition.workspace = true
license.workspace = true
description = "Raven's pathing tools"
repository.workspace = true
publish.workspace = true
test.workspace = true
[dependencies]
const_format.workspace = true

151
crates/path/src/lib.rs Normal file
View File

@@ -0,0 +1,151 @@
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
//TODO: Clean this up. Shouldn't need duplicated DIR_SRC consts about the workspace.
const DIR_SRC: &str = "src/";
const DIR_TARGET: &str = "target/";
const DIR_MAIN: &str = const_format::concatcp!(DIR_SRC, "main/");
const DIR_TEST: &str = const_format::concatcp!(DIR_SRC, "test/");
#[derive(Debug, Clone)]
pub struct PathHandler {
root_path: PathBuf,
// This is a short-living binary. This doesn't need an LRU like Moka.
derived_path_cache: HashMap<String, PathBuf>,
}
impl PathHandler {
pub fn new(root_path: PathBuf) -> Self {
Self::from(root_path)
}
pub fn root_path(&self) -> PathBuf {
self.root_path.clone()
}
/// This is a readability helper.
/// Make sure to set the root of this `PathHandler` to the project root.
/// This simply calls upon the root_path() of the `PathHandler`.
pub fn project_root(&self) -> PathBuf {
self.root_path()
}
pub fn dir_src(&mut self) -> PathBuf {
self.get_path(DIR_SRC)
}
pub fn dir_target(&mut self) -> PathBuf {
self.get_path(DIR_TARGET)
}
pub fn dir_main(&mut self) -> PathBuf {
self.get_path(DIR_MAIN)
}
pub fn dir_test(&mut self) -> PathBuf {
self.get_path(DIR_TEST)
}
/// Attempts to load from cache, else generates the path and clones it to the cache.
/// Returns the requested path.
fn get_path<S>(&mut self, k: S) -> PathBuf
where
S: ToString + AsRef<str>,
{
self.from_cache(k.as_ref())
.unwrap_or_else(|| {
self.gen_key(k.to_string(), self.root_path().join(k.to_string()));
self.get_path(k.as_ref())
})
.to_path_buf()
}
/// Attempts to pull the value for the given key from the cache.
fn from_cache<S: AsRef<str>>(&self, path_key: S) -> Option<PathBuf> {
self.derived_path_cache
.get(path_key.as_ref())
.and_then(|v| Some(v.to_owned()))
}
/// Tries to generate a new key-value pair in the cache
fn gen_key<P, S>(&mut self, k: S, v: P) -> Option<PathBuf>
where
P: AsRef<Path>,
S: ToString,
{
self.derived_path_cache
.insert(k.to_string(), v.as_ref().to_path_buf())
}
}
impl<P> From<P> for PathHandler
where
P: AsRef<Path>,
{
fn from(value: P) -> Self {
Self {
root_path: value.as_ref().to_path_buf(),
derived_path_cache: Default::default(),
}
}
}
pub trait PathHandled {
fn set_path_handler(&mut self, ph: Arc<Mutex<PathHandler>>) {}
fn with_path_handler(&mut self, ph: Arc<Mutex<PathHandler>>) -> &mut Self {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
const ROOT: &str = "/root";
#[test]
fn ph_get_path() {
let root = PathBuf::from(ROOT);
let expected = root.join(DIR_SRC);
let mut ph = PathHandler::from(root);
assert!(ph.dir_src() == expected);
}
#[test]
fn ph_cache_gen() {
let root = PathBuf::from(ROOT);
let expected = root.join(DIR_SRC);
let ph = PathHandler::from(root);
assert!(
ph.derived_path_cache
.get(DIR_SRC)
.is_some_and(|v| *v == expected)
);
}
#[test]
fn ph_cache_pull() {
let faux_path = "faux/path";
let mut ph = PathHandler::from("false/root");
ph.derived_path_cache
.insert(faux_path.to_string(), PathBuf::from(faux_path));
// Use the method that attempts a fallback.
// By using a false root, this will create a different path to the injected one,
// making it possible to determine if the cache load fails.
//
// I.e.
// Expected: faux/path as PathBuf
// Failed: false/root/faux/path as PathBuf
assert!(ph.get_path(faux_path) == PathBuf::from(faux_path));
}
}