use serde_yaml::{Mapping, Value as Yaml};
pub(crate) const TOP_FIELDS: [&str; 3] = ["name", "description", "steps"];
pub(crate) const STEP_FIELDS: [&str; 4] = ["name", "description", "executor", "criteria"];
pub(crate) const CRITERION_FIELDS: [&str; 7] = [
"executor",
"description",
"path",
"absent",
"file",
"contains",
"run",
];
pub(crate) fn text_of(value: &Yaml, key: &str) -> String {
value
.get(key)
.and_then(|v| v.as_str())
.unwrap_or("")
.trim()
.to_string()
}
pub(crate) fn unknown_fields(mapping: &Mapping, allowed: &[&str]) -> Vec<String> {
mapping
.keys()
.filter_map(|key| key.as_str())
.filter(|key| !allowed.contains(key))
.map(|key| key.to_string())
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
fn yaml(value: serde_json::Value) -> Yaml {
serde_yaml::to_value(value).expect("JSON 装成 YAML 值")
}
#[test]
fn text_of_trims_and_ignores_non_strings() {
let value = yaml(json!({"name": " demo ", "count": 3, "flag": true}));
assert_eq!(text_of(&value, "name"), "demo");
assert_eq!(text_of(&value, "count"), "", "数字不当字符串");
assert_eq!(text_of(&value, "flag"), "");
assert_eq!(text_of(&value, "missing"), "");
}
#[test]
fn unknown_fields_names_the_odd_ones() {
let mut mapping = Mapping::new();
mapping.insert(Yaml::String("name".into()), Yaml::String("x".into()));
mapping.insert(Yaml::String("extra".into()), Yaml::Bool(true));
mapping.insert(Yaml::Number(1.into()), Yaml::Null);
assert_eq!(unknown_fields(&mapping, &["name"]), vec!["extra"]);
assert!(unknown_fields(&mapping, &["name", "extra"]).is_empty());
}
}