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