1use std::path::{Path, PathBuf};
2
3pub fn route_from_path(content_dir: PathBuf, path: PathBuf) -> String {
4 let relative_path = match path.strip_prefix(&content_dir) {
6 Ok(p) => p,
7 Err(_) => {
8 panic!(
14 "Warning: Path {:?} is not within content directory {:?}",
15 path, content_dir
16 );
17 }
18 };
19
20 let mut route_parts: Vec<String> = relative_path
21 .components()
22 .filter_map(|c| {
23 match c {
25 std::path::Component::Normal(os_str) => Some(os_str.to_string_lossy().into_owned()),
26 _ => None,
27 }
28 })
29 .collect();
30
31 if let Some(last_segment) = route_parts.pop() {
33 let original_filename_path = Path::new(&last_segment);
34
35 if original_filename_path.file_stem().is_some() {
36 let stem = original_filename_path
37 .file_stem()
38 .unwrap()
39 .to_string_lossy();
40
41 if stem == "index" {
42 } else {
47 route_parts.push(stem.into_owned());
50 }
51 }
52 }
53
54 let mut route = format!("/{}", route_parts.join("/"));
56
57 if route.len() > 1 {
59 route.push('/');
60 }
61
62 if relative_path.to_string_lossy() == "index.md" {
65 route = "/".to_string();
66 }
67
68 route
69}
70
71#[cfg(test)]
72mod test {
73 use crate::Weaver;
74
75 use super::*;
76
77 use pretty_assertions::assert_eq;
78
79 #[test]
80 fn test_route_from_path() {
81 let base_path_wd = std::env::current_dir().unwrap().display().to_string();
82 let base_path = format!("{}/test_fixtures/config", base_path_wd);
83 let inst = Weaver::new(format!("{}/custom_config", base_path).into());
84
85 assert_eq!(
86 "/blog/post1/",
87 route_from_path(
88 inst.config.content_dir.clone().into(),
89 format!("{}/blog/post1.md", inst.config.content_dir).into()
90 )
91 );
92 }
93
94 #[test]
95 #[should_panic]
96 fn test_content_out_of_path() {
97 let base_path_wd = std::env::current_dir().unwrap().display().to_string();
98 let base_path = format!("{}/test_fixtures/config", base_path_wd);
99 let inst = Weaver::new(format!("{}/custom_config", base_path).into());
100 route_from_path(
101 inst.config.content_dir.clone().into(),
102 "madeup/blog/post1.md".into(),
103 );
104 }
105}