use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct StaticFiles {
mount_path: String,
directory: PathBuf,
index_file: Option<String>,
spa_fallback: bool,
}
impl StaticFiles {
#[must_use]
pub fn new(mount_path: impl Into<String>, directory: impl Into<PathBuf>) -> Self {
Self {
mount_path: mount_path.into(),
directory: directory.into(),
index_file: None,
spa_fallback: false,
}
}
#[must_use]
pub fn index_file(mut self, index: impl Into<String>) -> Self {
self.index_file = Some(index.into());
self
}
#[must_use]
pub const fn spa_fallback(mut self, enabled: bool) -> Self {
self.spa_fallback = enabled;
self
}
#[must_use]
pub fn mount_path(&self) -> &str {
&self.mount_path
}
#[must_use]
pub const fn directory(&self) -> &PathBuf {
&self.directory
}
#[must_use]
pub fn index_file_name(&self) -> Option<&str> {
self.index_file.as_deref()
}
#[must_use]
pub const fn is_spa_fallback(&self) -> bool {
self.spa_fallback
}
#[must_use]
pub fn effective_index_file(&self) -> Option<&str> {
if self.index_file.is_some() {
self.index_file.as_deref()
} else if self.spa_fallback {
Some("index.html")
} else {
None
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_static_files_new() {
let config = StaticFiles::new("/static", "./public");
assert_eq!(config.mount_path(), "/static");
assert_eq!(config.directory(), &PathBuf::from("./public"));
assert!(config.index_file_name().is_none());
assert!(!config.is_spa_fallback());
}
#[test]
fn test_static_files_index_file() {
let config = StaticFiles::new("/", "./dist").index_file("index.html");
assert_eq!(config.index_file_name(), Some("index.html"));
}
#[test]
fn test_static_files_spa_fallback() {
let config = StaticFiles::new("/", "./dist").spa_fallback(true);
assert!(config.is_spa_fallback());
assert_eq!(config.effective_index_file(), Some("index.html"));
}
#[test]
fn test_static_files_full_config() {
let config = StaticFiles::new("/app", "./build")
.index_file("app.html")
.spa_fallback(true);
assert_eq!(config.mount_path(), "/app");
assert_eq!(config.directory(), &PathBuf::from("./build"));
assert_eq!(config.index_file_name(), Some("app.html"));
assert!(config.is_spa_fallback());
assert_eq!(config.effective_index_file(), Some("app.html"));
}
#[test]
fn test_static_files_clone() {
let config = StaticFiles::new("/static", "./public")
.index_file("index.html")
.spa_fallback(true);
let cloned = config.clone();
assert_eq!(cloned.mount_path(), config.mount_path());
assert_eq!(cloned.directory(), config.directory());
assert_eq!(cloned.index_file_name(), config.index_file_name());
assert_eq!(cloned.is_spa_fallback(), config.is_spa_fallback());
}
}