use serde_yaml::Value;
use crate::frontmatter::Frontmatter;
pub fn value_label(val: &Value) -> String {
val.as_str()
.map(str::to_owned)
.unwrap_or_else(|| format!("{val:?}"))
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InvocabilityField {
pub value: Value,
pub consumed_key: String,
}
pub fn find_invocability_field(fm: &Frontmatter, kebab_key: &str) -> Option<InvocabilityField> {
if let Some(value) = fm.get(kebab_key) {
return Some(InvocabilityField {
value: value.clone(),
consumed_key: kebab_key.to_string(),
});
}
let snake = kebab_key.replace('-', "_");
fm.get(&snake).map(|value| InvocabilityField {
value: value.clone(),
consumed_key: snake,
})
}
pub fn parse_invocability_axis(raw: Option<&Value>) -> (bool, bool, Option<String>) {
match raw {
Some(raw) => match raw.as_bool() {
Some(value) => (value, true, None),
None => (true, false, Some(value_label(raw))),
},
None => (true, false, None),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::frontmatter::Frontmatter;
#[test]
fn find_invocability_field_prefers_kebab_when_both_present() {
let fm = Frontmatter::parse("---\nmodel-invocable: false\nmodel_invocable: true\n---\n")
.unwrap();
let field = find_invocability_field(&fm, "model-invocable").unwrap();
assert_eq!(field.consumed_key, "model-invocable");
assert_eq!(field.value, Value::Bool(false));
}
#[test]
fn find_invocability_field_reports_snake_alias() {
let fm = Frontmatter::parse("---\nmodel_invocable: false\n---\n").unwrap();
let field = find_invocability_field(&fm, "model-invocable").unwrap();
assert_eq!(field.consumed_key, "model_invocable");
assert_eq!(field.value, Value::Bool(false));
}
}