1pub mod helpers;
2mod routes;
3mod server;
4mod static_files;
5
6pub use server::serve;
7
8use std::sync::OnceLock;
9
10static BASE_PATH: OnceLock<String> = OnceLock::new();
11
12pub(crate) fn bp() -> &'static str {
14 BASE_PATH.get().map(|s| s.as_str()).unwrap_or("")
15}
16
17pub(crate) fn normalize_base_path(path: Option<&str>) -> crate::Result<String> {
21 match path {
22 None => Ok(String::new()),
23 Some(p) => {
24 let trimmed = p.trim().trim_matches('/');
25 if trimmed.is_empty() {
26 Ok(String::new())
27 } else if !trimmed
28 .chars()
29 .all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
30 {
31 Err(miette::miette!(
32 "PITCHFORK_WEB_PATH must contain only alphanumeric characters, hyphens, or underscores, got: {trimmed:?}"
33 ))
34 } else {
35 Ok(format!("/{trimmed}"))
36 }
37 }
38 }
39}