1#![forbid(unsafe_code)]
2mod command;
3mod execute;
4mod lsp;
5mod parse;
6
7pub enum RunFailure {
19 PolicyViolation(String),
22 Tool(String),
25}
26
27impl std::fmt::Display for RunFailure {
28 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 match self {
30 RunFailure::PolicyViolation(msg) | RunFailure::Tool(msg) => f.write_str(msg),
31 }
32 }
33}
34
35impl From<String> for RunFailure {
39 fn from(msg: String) -> Self {
40 RunFailure::Tool(msg)
41 }
42}
43
44pub fn run(args: impl IntoIterator<Item = String>) -> Result<(), RunFailure> {
45 let command = parse::parse(args).map_err(RunFailure::Tool)?;
46 execute::execute(command)
47}
48
49#[cfg(test)]
50mod tests {
51 use super::RunFailure;
52
53 #[test]
54 fn string_converts_to_tool_variant() {
55 let f: RunFailure = "some tool error".to_string().into();
56 assert!(
57 matches!(f, RunFailure::Tool(_)),
58 "From<String> must map to RunFailure::Tool, not PolicyViolation"
59 );
60 }
61
62 #[test]
63 fn display_shows_inner_message() {
64 let tool = RunFailure::Tool("tool message".to_string());
65 assert_eq!(tool.to_string(), "tool message");
66 let policy = RunFailure::PolicyViolation("policy message".to_string());
67 assert_eq!(policy.to_string(), "policy message");
68 }
69}