1use serde::Serialize;
6use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum OutputFormat {
11 Text,
13 Json,
15}
16
17impl std::str::FromStr for OutputFormat {
18 type Err = String;
19
20 fn from_str(s: &str) -> Result<Self, Self::Err> {
21 match s.to_lowercase().as_str() {
22 "text" | "txt" => Ok(OutputFormat::Text),
23 "json" => Ok(OutputFormat::Json),
24 _ => Err(format!("Invalid output format: {s}")),
25 }
26 }
27}
28
29pub struct OutputFormatter {
31 format: OutputFormat,
32}
33
34impl OutputFormatter {
35 pub fn new(format: OutputFormat) -> Self {
37 Self { format }
38 }
39
40 pub fn format<T>(&self, value: &T) -> Result<String, String>
42 where
43 T: Serialize + fmt::Display,
44 {
45 match self.format {
46 OutputFormat::Text => Ok(value.to_string()),
47 OutputFormat::Json => serde_json::to_string_pretty(value)
48 .map_err(|e| format!("JSON serialization error: {e}")),
49 }
50 }
51
52 pub fn format_error(&self, error: &dyn std::error::Error) -> String {
54 match self.format {
55 OutputFormat::Text => format!("Error: {error}"),
56 OutputFormat::Json => {
57 let error_json = serde_json::json!({
58 "error": true,
59 "message": error.to_string()
60 });
61 serde_json::to_string_pretty(&error_json)
62 .unwrap_or_else(|_| format!("{{\"error\": true, \"message\": \"{error}\"}}"))
63 }
64 }
65 }
66
67 pub fn format_success(&self, message: &str) -> String {
69 match self.format {
70 OutputFormat::Text => format!("Success: {message}"),
71 OutputFormat::Json => {
72 let success_json = serde_json::json!({
73 "success": true,
74 "message": message
75 });
76 serde_json::to_string_pretty(&success_json).unwrap_or_else(|_| {
77 format!("{{\"success\": true, \"message\": \"{message}\"}}")
78 })
79 }
80 }
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_output_format_parsing() {
90 assert_eq!("text".parse::<OutputFormat>().unwrap(), OutputFormat::Text);
91 assert_eq!("txt".parse::<OutputFormat>().unwrap(), OutputFormat::Text);
92 assert_eq!("json".parse::<OutputFormat>().unwrap(), OutputFormat::Json);
93 assert!("invalid".parse::<OutputFormat>().is_err());
94 }
95
96 #[test]
97 fn test_text_formatting() {
98 let formatter = OutputFormatter::new(OutputFormat::Text);
99 let result = formatter.format(&"test message");
100 assert_eq!(result.unwrap(), "test message");
101 }
102
103 #[test]
104 fn test_json_formatting() {
105 let formatter = OutputFormatter::new(OutputFormat::Json);
106 let result = formatter.format(&serde_json::json!({"message": "test"}));
107 assert!(result.unwrap().contains("test"));
108 }
109}