use yaml_rust2::Yaml;
use super::Problem;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(super) enum Strictness {
Lenient,
Strict,
}
pub(super) const WINDOW_KEYS: &[&str] = &[
"window_name",
"window_index",
"window_shell",
"environment",
"layout",
"start_directory",
"focus",
"options",
"shell_command_before",
"suppress_history",
"panes",
];
pub(super) const WINDOW_RECOGNIZED: &[&str] = &["options_after"];
pub(super) const PANE_KEYS: &[&str] = &[
"shell_command",
"shell_command_before",
"environment",
"start_directory",
"focus",
"shell",
"enter",
"sleep_before",
"sleep_after",
"suppress_history",
];
pub(super) const SESSION_KEYS: &[&str] = &[
"session_name",
"start_directory",
"environment",
"options",
"global_options",
"shell_command_before",
"suppress_history",
"windows",
];
pub(super) const SESSION_RECOGNIZED: &[&str] = &[
"before_script",
"plugins",
"workspace_builder",
"workspace_builder_options",
"config",
"socket_name",
];
pub(super) fn has_key(value: &Yaml, key: &str) -> bool {
matches!(value, Yaml::Hash(entries) if entries.contains_key(&Yaml::String(key.to_owned())))
}
pub(super) fn check_known(
value: &Yaml,
known: &[&str],
extra: &[&str],
strictness: Strictness,
at: &str,
) -> Result<(), Problem> {
if strictness == Strictness::Lenient {
return Ok(());
}
let Yaml::Hash(entries) = value else {
return Ok(());
};
for key in entries.keys().filter_map(Yaml::as_str) {
if key.starts_with("x-") || known.contains(&key) || extra.contains(&key) {
continue;
}
let path = if at.is_empty() {
key.to_owned()
} else {
format!("{at}.{key}")
};
return Err(Problem::new(
path,
"is not a key this parser acts on; prefix it x- to keep it inert, \
or read this document with Workspace::from_yaml instead",
));
}
Ok(())
}
pub(super) fn unsupported(document: &Yaml, known: &[&str]) -> Vec<String> {
let Yaml::Hash(entries) = document else {
return Vec::new();
};
entries
.keys()
.filter_map(|key| key.as_str())
.filter(|key| !known.contains(key))
.map(ToOwned::to_owned)
.collect()
}