1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
use std::collections::HashMap;
use uuid::Uuid;
use crate::data::PageUuid;
use std::{
fs,
path::{Path, PathBuf},
};
#[derive(Clone, Debug)]
pub struct Namespace {
pub page: Option<PageUuid>,
pub children: HashMap<String, Namespace>,
}
pub struct Namespaces {
pub root: Namespace,
}
impl Namespace {
pub fn new() -> Self {
Self {
page: None,
children: HashMap::new(),
}
}
}
impl Namespaces {
pub fn init(namespaces_dir: &Path) -> Result<Self, String> {
// Read dir recursive
let mut paths = Vec::new();
Self::scan_dir(namespaces_dir, &mut paths);
let paths = paths
.into_iter()
.map(|path| PathBuf::from(path.strip_prefix(namespaces_dir).unwrap()))
.collect::<Vec<_>>();
// Build lookup
let mut root = Namespace::new();
for path in paths {
let mut current_node = &mut root;
for segment in path.iter() {
let segment = segment.to_string_lossy().to_string();
if segment == "_page" {
let link_target = namespaces_dir.join(&path).read_link().unwrap();
let uuid_string = link_target.file_name().unwrap().to_str().unwrap();
let page_uuid = PageUuid(Uuid::try_parse(uuid_string).unwrap());
current_node.page = Some(page_uuid);
} else {
current_node
.children
.insert(segment.clone(), Namespace::new());
current_node = current_node.children.get_mut(&segment).unwrap();
}
}
}
Ok(Self { root })
}
pub fn get_page_uuid(&self, path: &String) -> Option<PageUuid> {
let mut current_namespace = &self.root;
for segment in path.trim_matches('/').split('/') {
current_namespace = current_namespace.children.get(segment)?;
}
current_namespace.page.clone()
}
pub fn remove_page(&self, path: String) -> Result<(), String> {
todo!()
}
pub fn add_page(&self, path: String, uuid: PageUuid) -> Result<(), String> {
todo!()
}
fn scan_dir(current_dir: &Path, out_vec: &mut Vec<PathBuf>) {
if !current_dir.is_dir() {
return;
}
for entry in fs::read_dir(current_dir).unwrap() {
let entry_path = entry.unwrap().path();
if entry_path.is_dir() && !entry_path.is_symlink() {
Self::scan_dir(&entry_path, out_vec);
} else {
out_vec.push(entry_path.into());
}
}
}
}
|