use anyhow::{Result, anyhow};
use serde_yaml_ng::Sequence;
pub const BUILTIN: &str = "tags";
pub fn parse(seq: Option<&Sequence>) -> Result<Vec<String>> {
let mut taxonomies: Vec<String> = Vec::new();
let Some(seq) = seq else {
return Ok(taxonomies);
};
for value in seq {
let name = value
.as_str()
.ok_or_else(|| anyhow!("taxonomies: entries must be strings"))?;
if !taxonomies.iter().any(|t| t == name) {
taxonomies.push(name.to_string());
}
}
Ok(taxonomies)
}
#[cfg(test)]
mod tests {
use super::*;
fn yaml(s: &str) -> Sequence {
serde_yaml_ng::from_str(s).unwrap()
}
#[test]
fn none_yields_empty() {
let t = parse(None).unwrap();
assert!(t.is_empty());
}
#[test]
fn parses_in_declaration_order() {
let s = yaml("- tags\n- categories\n- series\n");
let t = parse(Some(&s)).unwrap();
assert_eq!(t, vec!["tags", "categories", "series"]);
}
#[test]
fn duplicates_are_skipped() {
let s = yaml("- tags\n- categories\n- tags\n");
let t = parse(Some(&s)).unwrap();
assert_eq!(t, vec!["tags", "categories"]);
}
#[test]
fn non_string_entry_errors() {
let s = yaml("- tags\n- 7\n");
assert!(parse(Some(&s)).is_err());
}
}