use crate::document::InterpretedValue;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum SafeMode {
Unsafe = 0,
Safe = 1,
Server = 10,
#[default]
Secure = 20,
}
impl SafeMode {
pub(crate) fn name(self) -> &'static str {
match self {
Self::Unsafe => "unsafe",
Self::Safe => "safe",
Self::Server => "server",
Self::Secure => "secure",
}
}
pub(crate) fn level(self) -> u8 {
self as u8
}
}
pub(crate) fn masked_doc_path(
name: &str,
raw_set_value: impl Fn(&str) -> Option<String>,
) -> Option<InterpretedValue> {
match name {
"docdir" => raw_set_value("docdir").map(|_| InterpretedValue::Value(String::new())),
"docfile" => {
let docfile = raw_set_value("docfile")?;
let relative = relativize_docfile(&docfile, raw_set_value("docdir").as_deref());
Some(InterpretedValue::Value(relative))
}
_ => None,
}
}
fn relativize_docfile(docfile: &str, docdir: Option<&str>) -> String {
if let Some(docdir) = docdir.map(|d| d.trim_end_matches(['/', '\\']))
&& !docdir.is_empty()
&& let Some(rest) = docfile.strip_prefix(docdir)
&& let Some(after) = rest.strip_prefix(['/', '\\'])
{
return after.to_owned();
}
docfile
.rsplit(['/', '\\'])
.next()
.unwrap_or(docfile)
.to_owned()
}
#[cfg(test)]
mod tests {
use super::relativize_docfile;
#[test]
fn strips_exact_docdir_prefix() {
assert_eq!(
relativize_docfile("/some/dir/sample.adoc", Some("/some/dir")),
"sample.adoc"
);
}
#[test]
fn keeps_subdirectories_below_docdir() {
assert_eq!(
relativize_docfile("/some/dir/sub/sample.adoc", Some("/some/dir")),
"sub/sample.adoc"
);
}
#[test]
fn strips_a_backslash_separated_prefix() {
assert_eq!(
relativize_docfile(r"C:\some\dir\sample.adoc", Some(r"C:\some\dir")),
"sample.adoc"
);
}
#[test]
fn falls_back_to_base_name_when_docfile_is_not_under_docdir() {
assert_eq!(
relativize_docfile("/some/different/file.adoc", Some("/some/dir")),
"file.adoc"
);
}
#[test]
fn falls_back_to_base_name_when_prefix_is_not_separator_aligned() {
assert_eq!(
relativize_docfile("/some/dirfile.adoc", Some("/some/dir")),
"dirfile.adoc"
);
}
#[test]
fn ignores_a_trailing_separator_on_docdir() {
assert_eq!(
relativize_docfile("/some/dir/sub/sample.adoc", Some("/some/dir/")),
"sub/sample.adoc"
);
assert_eq!(
relativize_docfile("/some/dir/sample.adoc", Some("/some/dir/")),
"sample.adoc"
);
assert_eq!(
relativize_docfile("/some/dir/sub/sample.adoc", Some("/some/dir///")),
"sub/sample.adoc"
);
assert_eq!(
relativize_docfile(r"C:\some\dir\sub\sample.adoc", Some(r"C:\some\dir\")),
r"sub\sample.adoc"
);
}
#[test]
fn treats_empty_docdir_as_no_prefix() {
assert_eq!(
relativize_docfile("/some/dir/sample.adoc", Some("")),
"sample.adoc"
);
}
#[test]
fn falls_back_to_base_name_without_a_docdir() {
assert_eq!(
relativize_docfile("/some/dir/sample.adoc", None),
"sample.adoc"
);
}
#[test]
fn returns_a_bare_docfile_unchanged() {
assert_eq!(relativize_docfile("sample.adoc", None), "sample.adoc");
assert_eq!(
relativize_docfile("sample.adoc", Some("/some/dir")),
"sample.adoc"
);
}
}