1use crate::cube::FormatConfig;
6use crate::{CodegenError, Result};
7
8#[derive(Debug)]
10pub struct Formatter;
11
12impl Formatter {
13 #[must_use]
15 pub const fn new() -> Self {
16 Self
17 }
18
19 pub fn format(&self, content: &str, language: &str, config: &FormatConfig) -> Result<String> {
25 match language {
26 "json" => self.format_json(content, config),
27 "typescript" | "javascript" => {
28 Ok(content.to_string())
31 }
32 "rust" => {
33 Ok(content.to_string())
36 }
37 _ => Ok(content.to_string()),
38 }
39 }
40
41 #[allow(clippy::unused_self)] fn format_json(&self, content: &str, config: &FormatConfig) -> Result<String> {
44 let value: serde_json::Value = serde_json::from_str(content)?;
45
46 let indent_size = config.indent_size.unwrap_or(2);
47 let indent_char = if config.indent == "tab" { '\t' } else { ' ' };
48
49 let formatted = if indent_char == '\t' {
50 serde_json::to_string_pretty(&value)?
51 } else {
52 let mut buf = Vec::new();
53 let indent = vec![b' '; indent_size];
54 let formatter = serde_json::ser::PrettyFormatter::with_indent(indent.as_slice());
55 let mut ser = serde_json::Serializer::with_formatter(&mut buf, formatter);
56 serde::Serialize::serialize(&value, &mut ser)
57 .map_err(|e| CodegenError::Formatting(e.to_string()))?;
58 String::from_utf8(buf).map_err(|e| CodegenError::Formatting(e.to_string()))?
59 };
60
61 Ok(formatted)
62 }
63}
64
65impl Default for Formatter {
66 fn default() -> Self {
67 Self::new()
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_format_json() {
77 let fmt = Formatter::new();
78 let input = r#"{"name":"test","value":123}"#;
79 let config = FormatConfig {
80 indent: "space".to_string(),
81 indent_size: Some(2),
82 ..Default::default()
83 };
84
85 let result = fmt.format(input, "json", &config);
86 assert!(result.is_ok());
87
88 let output = result.unwrap();
89 assert!(output.contains(" ")); assert!(output.contains("\"name\": \"test\""));
91 }
92
93 #[test]
94 fn test_format_unknown_language() {
95 let formatter = Formatter::new();
96 let input = "some content";
97 let config = FormatConfig::default();
98
99 let result = formatter.format(input, "unknown", &config);
100 assert!(result.is_ok());
101 assert_eq!(result.unwrap(), input);
102 }
103}