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
use crate::tree::LinkLocation;
use std::borrow::Cow;
use wikidot_normalize::normalize;
pub const URL_SCHEMES: [&str; 20] = [
"blob:",
"chrome-extension://",
"chrome://",
"content://",
"data:",
"dns:",
"feed:",
"file://",
"ftp://",
"git://",
"gopher://",
"http://",
"https://",
"irc6://",
"irc://",
"ircs://",
"mailto:",
"resource://",
"rtmp://",
"sftp://",
];
pub fn is_url(url: &str) -> bool {
for scheme in &URL_SCHEMES {
if url.starts_with(scheme) {
return true;
}
}
false
}
pub fn normalize_link<'a>(
link: &'a LinkLocation<'a>,
helper: &dyn BuildSiteUrl,
) -> Cow<'a, str> {
match link {
LinkLocation::Url(url) => normalize_href(url),
LinkLocation::Page(page_ref) => {
let (site, page) = page_ref.fields();
match site {
Some(site) => Cow::Owned(helper.build_url(site, page)),
None => normalize_href(page),
}
}
}
}
pub fn normalize_href(url: &str) -> Cow<str> {
if is_url(url) || url.starts_with('#') || url == "javascript:;" {
Cow::Borrowed(url)
} else {
let mut url = str!(url);
normalize(&mut url);
url.insert(0, '/');
Cow::Owned(url)
}
}
pub trait BuildSiteUrl {
fn build_url(&self, site: &str, path: &str) -> String;
}