about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.vscode/settings.json5
-rwxr-xr-xreadme.md1
-rwxr-xr-xsrc/fs.rs61
3 files changed, 66 insertions, 1 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..4b69635
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+	"cSpell.enableFiletypes": [
+		"!rust"
+	]
+}
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 5bc226f..ebb7350 100755
--- a/readme.md
+++ b/readme.md
@@ -23,6 +23,7 @@ service.
 
 TODO:
 - [] don't log referer if it's ourself
+- [] unstub Filesystem::reverse_resolve.
 
 ## Dirfiles
 These are files that match the name of the directory.
diff --git a/src/fs.rs b/src/fs.rs
index 831aa86..e47889b 100755
--- a/src/fs.rs
+++ b/src/fs.rs
@@ -1,6 +1,6 @@
 use camino::{Utf8Path, Utf8PathBuf};
 use core::fmt;
-use std::{io, ops::Deref, str::FromStr};
+use std::{fmt, io, ops::Deref, str::FromStr};
 
 use crate::RuntimeError;
 
@@ -154,6 +154,46 @@ impl Filesystem {
 		}
 	}
 
+	/// Resolve a file system path to a webpath.
+	///
+	/// Paths are not checked to see if they exist and are not checked to be within the webroot.
+	///
+	/// Paths attempt to resolve to the simplest form. For example, if the path is [`ROOT_INDEX`]
+	/// it will come out as `/` and if it is a dirfile, it will come out as a directory.
+	///
+	/// **FOOTGUN** currently assumes every path is a file...
+	pub fn reverse_resolve<P: AsRef<Utf8Path>>(&self, path: P) -> Result<Webpath, RuntimeError> {
+		let path = path.as_ref();
+		let relpath = match path.strip_prefix(&self.webroot) {
+			Ok(relpath) => relpath,
+			Err(_e) => {
+				if path.is_relative() {
+					path
+				} else {
+					//FIXME: gen- This error is not strictly correct, but it'll do for now.
+					// 2024-10-12
+					return Err(RuntimeError::PathTooLow {
+						path: path.to_string(),
+					});
+				}
+			}
+		};
+
+		if relpath == "" || relpath == ROOT_INDEX {
+			return Ok(Webpath {
+				webcanon: Utf8PathBuf::new(),
+				is_dir: true,
+			});
+		}
+
+		todo!();
+
+		Ok(Webpath {
+			webcanon: relpath.into(),
+			is_dir: false,
+		})
+	}
+
 	pub fn metadata<P: AsRef<Utf8Path>>(path: P) -> Result<std::fs::Metadata, RuntimeError> {
 		path.as_ref()
 			.metadata()
@@ -248,4 +288,23 @@ mod test {
 			format!("{TESTROOT}/one/one.html")
 		);
 	}
+
+	#[test]
+	fn filesystem_reverse_resolves_index() {
+		let fs = Filesystem::new(TESTROOT);
+
+		assert_eq!(fs.reverse_resolve(TESTROOT).unwrap(), webpath!("/"));
+		assert_eq!(
+			fs.reverse_resolve(format!("{TESTROOT}/{ROOT_INDEX}"))
+				.unwrap(),
+			webpath!("/")
+		)
+	}
+
+	#[test]
+	fn filesystem_reverse_resolves_directories() {
+		let fs = Filesystem::new(TESTROOT);
+
+		assert_eq!(fs.reverse_resolve("test/").unwrap(), webpath!("test/"))
+	}
 }