result.rs (3215B)
1 use std::fmt; 2 3 /// Result type for ChatOps command execution 4 #[derive(Debug, Clone)] 5 pub enum ChatOpResult { 6 /// Single message to send to chat 7 Message(String), 8 /// Multiple lines/blocks to send (paginated if needed) 9 Block(Vec<String>), 10 /// No output (silent success) 11 #[allow(dead_code)] 12 Silent, 13 /// Formatted code block 14 CodeBlock(String, Option<String>), // content, language 15 /// Error message 16 Error(String), 17 } 18 19 impl ChatOpResult { 20 /// Convert to strings for chat output 21 pub fn to_messages(&self) -> Vec<String> { 22 match self { 23 ChatOpResult::Message(msg) => vec![msg.clone()], 24 ChatOpResult::Block(lines) => lines.clone(), 25 ChatOpResult::Silent => vec![], 26 ChatOpResult::CodeBlock(content, lang) => { 27 let lang_str = lang.as_deref().unwrap_or("text"); 28 vec![format!("```{}\n{}\n```", lang_str, content)] 29 } 30 ChatOpResult::Error(err) => vec![format!("❌ Error: {}", err)], 31 } 32 } 33 34 /// Check if result should be truncated for chat 35 pub fn should_truncate(&self, max_lines: usize) -> bool { 36 self.to_messages().len() > max_lines 37 } 38 39 /// Truncate result for chat output 40 pub fn truncate(&self, max_lines: usize) -> ChatOpResult { 41 let messages = self.to_messages(); 42 if messages.len() <= max_lines { 43 return self.clone(); 44 } 45 46 let message_count = messages.len(); 47 let mut truncated = messages.into_iter().take(max_lines - 1).collect::<Vec<_>>(); 48 truncated.push(format!( 49 "... ({} more lines truncated)", 50 message_count - max_lines + 1 51 )); 52 ChatOpResult::Block(truncated) 53 } 54 } 55 56 /// Error type for ChatOps commands 57 #[derive(Debug, Clone)] 58 pub enum ChatOpError { 59 /// Invalid command syntax 60 InvalidSyntax(String), 61 /// Missing required arguments 62 MissingArguments(String), 63 /// Permission denied 64 PermissionDenied(String), 65 /// External tool/service error 66 #[allow(dead_code)] 67 ExternalError(String), 68 /// Network/connectivity error 69 NetworkError(String), 70 /// File system error 71 #[allow(dead_code)] 72 FileSystemError(String), 73 /// Generic error with message 74 Generic(String), 75 } 76 77 impl fmt::Display for ChatOpError { 78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 79 match self { 80 ChatOpError::InvalidSyntax(msg) => write!(f, "Invalid syntax: {}", msg), 81 ChatOpError::MissingArguments(msg) => write!(f, "Missing arguments: {}", msg), 82 ChatOpError::PermissionDenied(msg) => write!(f, "Permission denied: {}", msg), 83 ChatOpError::ExternalError(msg) => write!(f, "External error: {}", msg), 84 ChatOpError::NetworkError(msg) => write!(f, "Network error: {}", msg), 85 ChatOpError::FileSystemError(msg) => write!(f, "File system error: {}", msg), 86 ChatOpError::Generic(msg) => write!(f, "{}", msg), 87 } 88 } 89 } 90 91 impl std::error::Error for ChatOpError {} 92 93 impl From<ChatOpError> for ChatOpResult { 94 fn from(error: ChatOpError) -> Self { 95 ChatOpResult::Error(error.to_string()) 96 } 97 }