use serde::Deserialize;
use std::path::PathBuf;
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct CommandSnippet {
pub description: String,
pub command: String,
#[serde(default)]
pub tags: Vec<String>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct FileDef {
pub commands: Vec<CommandSnippet>,
}
#[derive(Debug, Clone)]
pub struct CommandDef {
pub description: String,
pub command: String,
pub source_file: PathBuf,
pub tags: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::FileDef;
#[test]
fn test_filedef_deserialize_success() {
let toml_str = r#"
[[commands]]
description = "desc"
command = "echo hi"
tags = ["a", "b"]
"#;
let fd: FileDef = toml::from_str(toml_str).expect("Failed to parse FileDef");
assert_eq!(fd.commands.len(), 1);
let cs = &fd.commands[0];
assert_eq!(cs.description, "desc");
assert_eq!(cs.command, "echo hi");
assert_eq!(cs.tags, vec!["a".to_string(), "b".to_string()]);
}
#[test]
fn test_command_snippet_default_tags() {
let toml_str = r#"
[[commands]]
description = "no-tags"
command = "echo"
"#;
let fd: FileDef = toml::from_str(toml_str).expect("Failed to parse FileDef");
assert_eq!(fd.commands.len(), 1);
let cs = &fd.commands[0];
assert!(cs.tags.is_empty(), "Expected default empty tags");
}
#[test]
fn test_filedef_deny_unknown_fields() {
let toml_str = r#"
[[commands]]
description = "desc"
command = "echo"
unknown_field = 123
"#;
let result: Result<FileDef, _> = toml::from_str(toml_str);
assert!(result.is_err(), "Unknown field should cause error");
}
#[test]
fn test_missing_description_field() {
let toml_str = r#"[[commands]]
command = "echo hi"
"#;
let result: Result<FileDef, _> = toml::from_str(toml_str);
assert!(result.is_err(), "Missing description should error");
}
#[test]
fn test_missing_command_field() {
let toml_str = r#"[[commands]]
description = "desc"
"#;
let result: Result<FileDef, _> = toml::from_str(toml_str);
assert!(result.is_err(), "Missing command should error");
}
#[test]
fn test_missing_commands_array() {
let toml_str = "";
let result: Result<FileDef, _> = toml::from_str(toml_str);
assert!(result.is_err(), "Missing commands array should error");
}
}