-
-
Notifications
You must be signed in to change notification settings - Fork 177
Expand file tree
/
Copy pathfunctions.rs
More file actions
152 lines (142 loc) · 3.79 KB
/
Copy pathfunctions.rs
File metadata and controls
152 lines (142 loc) · 3.79 KB
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! Built-in `SQLPage` SQL functions.
//!
//! Every function is a plain `async fn` in its own module under [`functions/`](self). To add one,
//! create `functions/<name>.rs` with an `async fn <name>`, declare the module below and add it to
//! the [`sqlpage_functions!`](super::function_traits::sqlpage_functions) call. Argument conversion
//! and dispatch are handled generically in [`super::function_traits`].
use std::fmt::Write;
use super::function_traits::sqlpage_functions;
mod basic_auth_password;
mod basic_auth_username;
mod client_ip;
mod configuration_directory;
mod cookie;
mod current_working_directory;
mod environment_variable;
mod exec;
mod fetch;
mod fetch_with_meta;
mod hash_password;
mod header;
mod headers;
mod hmac;
mod link;
mod oidc_logout_url;
mod path;
mod persist_uploaded_file;
mod protocol;
mod random_string;
mod read_file_as_data_url;
mod read_file_as_text;
mod regex_match;
mod request_body;
mod request_body_base64;
mod request_method;
mod run_sql;
mod send_mail;
mod set_variable;
mod uploaded_file_mime_type;
mod uploaded_file_name;
mod uploaded_file_path;
mod url_encode;
mod user_info;
mod user_info_token;
mod variables;
mod version;
mod web_root;
sqlpage_functions! {
basic_auth_password,
basic_auth_username,
client_ip,
configuration_directory,
cookie,
current_working_directory,
environment_variable,
exec,
fetch,
fetch_with_meta,
hash_password,
header,
headers,
hmac,
link,
oidc_logout_url,
path,
persist_uploaded_file,
protocol,
random_string,
read_file_as_data_url,
read_file_as_text,
regex_match,
request_body,
request_body_base64,
request_method,
run_sql,
send_mail,
set_variable,
uploaded_file_mime_type,
uploaded_file_name,
uploaded_file_path,
url_encode,
user_info,
user_info_token,
variables,
version,
web_root,
}
impl ::std::str::FromStr for SqlPageFunctionName {
type Err = anyhow::Error;
fn from_str(name: &str) -> anyhow::Result<Self> {
SqlPageFunctionName::ALL
.iter()
.copied()
.find(|function| function.name().eq_ignore_ascii_case(name))
.ok_or_else(|| {
anyhow::anyhow!(
"Unknown function {name:?}. Supported functions:\n{}",
supported_function_list()
)
})
}
}
impl ::std::fmt::Display for SqlPageFunctionName {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
f.write_str("sqlpage.")?;
f.write_str(self.name())
}
}
fn supported_function_list() -> String {
let mut supported = String::new();
for function in SqlPageFunctionName::ALL {
writeln!(supported, " - {function}").expect("writing to a String cannot fail");
}
supported
}
#[cfg(test)]
mod tests {
use super::SqlPageFunctionName;
use std::collections::BTreeSet;
#[test]
fn functions_directory_matches_registered_functions() {
let directory = concat!(
env!("CARGO_MANIFEST_DIR"),
"/src/webserver/database/sqlpage_functions/functions"
);
let files: BTreeSet<String> = std::fs::read_dir(directory)
.expect("functions directory")
.map(|entry| entry.expect("directory entry").path())
.filter(|path| path.extension().is_some_and(|extension| extension == "rs"))
.map(|path| {
path.file_stem()
.expect("file stem")
.to_string_lossy()
.into_owned()
})
.collect();
let registered: BTreeSet<String> = SqlPageFunctionName::ALL
.iter()
.map(|function| function.name().to_owned())
.collect();
assert_eq!(files, registered);
}
}