use serde::Deserialize;
use crate::config::WorkflowConfig;
#[must_use]
pub fn extract_one_line_description(yaml: &str) -> Option<String> {
let desc = if let Ok(config) = WorkflowConfig::from_yaml(yaml) {
config.description
} else {
#[derive(Deserialize)]
struct DescriptionOnly {
description: Option<String>,
}
let parsed: DescriptionOnly = serde_yaml::from_str(yaml).ok()?;
parsed.description
}?;
let normalized = desc.split_whitespace().collect::<Vec<_>>().join(" ");
if normalized.is_empty() {
None
} else {
Some(normalized)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_extract_one_line_description_returns_description() {
let yaml = r"
command: [claude, -p]
description: 'team-shared workflow'
steps:
s1:
command: echo hi
";
let desc = extract_one_line_description(yaml);
assert_eq!(desc, Some("team-shared workflow".to_string()));
}
#[test]
fn test_extract_one_line_description_returns_none_when_absent() {
let yaml = r"
command: [claude, -p]
steps:
s1:
command: echo hi
";
let desc = extract_one_line_description(yaml);
assert_eq!(desc, None);
}
#[test]
fn test_extract_one_line_description_normalizes_multiline() {
let yaml = "command: [claude, -p]\ndescription: |\n line one\n line two\nsteps:\n s1:\n command: echo hi\n";
let desc = extract_one_line_description(yaml);
assert_eq!(desc, Some("line one line two".to_string()));
}
#[test]
fn test_extract_one_line_description_returns_none_for_invalid_yaml() {
let yaml = "not: valid: yaml: [unclosed";
let desc = extract_one_line_description(yaml);
assert_eq!(desc, None);
}
#[test]
fn test_extract_one_line_description_reads_via_workflow_config_parse() {
let yaml = r"
command: [claude, -p]
description: 'team-shared workflow'
steps:
s1:
command: echo hi
";
let config = WorkflowConfig::from_yaml(yaml).unwrap_or_else(|e| panic!("{e}"));
assert_eq!(config.description.as_deref(), Some("team-shared workflow"));
let desc = extract_one_line_description(yaml);
assert_eq!(desc, Some("team-shared workflow".to_string()));
}
#[test]
fn test_extract_one_line_description_falls_back_when_workflow_config_parse_fails() {
let yaml = "description: 'partial config'\n";
assert!(
WorkflowConfig::from_yaml(yaml).is_err(),
"expected this YAML to fail full WorkflowConfig parsing (missing `steps`)"
);
let desc = extract_one_line_description(yaml);
assert_eq!(desc, Some("partial config".to_string()));
}
}