From eec4635eba5077b274b9b93f6aa7bfc559d3343a Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Thu, 29 Jan 2026 15:15:43 +0000 Subject: [PATCH] Add source files: main, lib, cli, error, convert, highlight, validate, typescript --- src/highlight.rs | 196 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 src/highlight.rs diff --git a/src/highlight.rs b/src/highlight.rs new file mode 100644 index 0000000..661011c --- /dev/null +++ b/src/highlight.rs @@ -0,0 +1,196 @@ +use colored::Colorize; + +pub fn highlight_value(value: &serde_json::Value, indent: usize) -> String { + let indent_str = " ".repeat(indent); + let next_indent = " ".repeat(indent + 1); + + match value { + serde_json::Value::Null => format!("{}", indent_str).red().to_string(), + serde_json::Value::Bool(b) => { + if *b { + format!("{}", indent_str).magenta().bold().to_string() + } else { + format!("{}", indent_str).magenta().bold().to_string() + } + } + serde_json::Value::Number(n) => { + format!("{}{}", indent_str, n).yellow().to_string() + } + serde_json::Value::String(s) => { + format!("{}{}", indent_str, format!("\"{s}\"").green().to_string()) + } + serde_json::Value::Array(arr) => { + if arr.is_empty() { + format!("{}", indent_str).cyan().to_string() + } else { + let mut result = format!("{}", indent_str).cyan().to_string(); + for (i, item) in arr.iter().enumerate() { + result.push('\n'); + result.push_str(&highlight_value(item, indent + 1)); + if i < arr.len() - 1 { + result.push(','); + } + } + result.push('\n'); + result.push_str(&format!("{}", indent_str).cyan().to_string()); + result + } + } + serde_json::Value::Object(map) => { + if map.is_empty() { + format!("{}", indent_str).cyan().to_string() + } else { + let mut result = format!("{}", indent_str).cyan().to_string(); + let entries: Vec<_> = map.iter().collect(); + for (i, (key, value)) in entries.iter().enumerate() { + result.push('\n'); + result.push_str(&format!("{}", key.cyan().bold().to_string())); + result.push_str(": "); + result.push_str(&highlight_value(value, indent + 1)); + if i < entries.len() - 1 { + result.push(','); + } + } + result.push('\n'); + result.push_str(&format!("{}", "}".cyan().to_string())); + result + } + } + } +} + +pub fn highlight_yaml(content: &str) -> String { + let lines: Vec<&str> = content.lines().collect(); + let mut result = String::new(); + let mut indent_level = 0; + + for line in lines { + let trimmed = line.trim_start(); + let current_indent = line.len() - trimmed.len(); + + while current_indent < indent_level * 2 && indent_level > 0 { + indent_level -= 1; + result.push_str(&format!("{}{}}}", " ".repeat(indent_level), "}".cyan().to_string())); + result.push('\n'); + } + + if trimmed.is_empty() { + result.push('\n'); + continue; + } + + if trimmed.starts_with('#') { + result.push_str(&format!("{}{}", " ".repeat(indent_level), line.gray())); + continue; + } + + if trimmed.ends_with(':') { + let key = trimmed.trim_end_matches(':'); + result.push_str(&format!("{}{}:", " ".repeat(indent_level), key.cyan().bold())); + result.push('\n'); + indent_level += 1; + } else if let Some(colon_idx) = trimmed.find(':') { + let key = &trimmed[..colon_idx].trim(); + let value = &trimmed[colon_idx + 1..].trim(); + + result.push_str(&" ".repeat(indent_level)); + result.push_str(&key.cyan().bold().to_string()); + result.push_str(": "); + + if value.is_empty() { + result.push('\n'); + } else { + result.push_str(&highlight_yaml_value(value)); + result.push('\n'); + } + } else { + result.push_str(&format!("{}{}", " ".repeat(indent_level), trimmed)); + result.push('\n'); + } + } + + while indent_level > 0 { + indent_level -= 1; + result.push_str(&format!("{}{}}}", " ".repeat(indent_level), "}".cyan().to_string())); + result.push('\n'); + } + + result +} + +fn highlight_yaml_value(value: &str) -> String { + let trimmed = value.trim(); + if trimmed.starts_with('"') && trimmed.ends_with('"') { + let inner = &trimmed[1..trimmed.len() - 1]; + format!("\"{}\"", inner.green()) + } else if trimmed.starts_with("'") && trimmed.ends_with("'") { + let inner = &trimmed[1..trimmed.len() - 1]; + format!("'{}'", inner.green()) + } else if trimmed == "true" || trimmed == "false" { + trimmed.magenta().bold().to_string() + } else if trimmed == "null" || trimmed == "~" { + trimmed.red().to_string() + } else if trimmed.parse::().is_ok() { + trimmed.yellow().to_string() + } else { + trimmed.green().to_string() + } +} + +pub fn highlight_ini(content: &str) -> String { + let lines: Vec<&str> = content.lines().collect(); + let mut result = String::new(); + let mut in_section = false; + + for line in lines { + let trimmed = line.trim(); + + if trimmed.is_empty() { + result.push('\n'); + continue; + } + + if trimmed.starts_with('[') && trimmed.ends_with(']') { + result.push_str(&format!("[{}]\n", trimmed[1..trimmed.len() - 1].cyan().bold())); + in_section = true; + } else if trimmed.starts_with('#') || trimmed.starts_with(';') { + result.push_str(&format!("{}\n", line.gray())); + } else if let Some(eq_idx) = trimmed.find('=') { + let key = &trimmed[..eq_idx].trim(); + let value = &trimmed[eq_idx + 1..].trim(); + result.push_str(&key.cyan().bold().to_string()); + result.push_str(" = "); + result.push_str(&value.green().to_string()); + result.push('\n'); + } else { + result.push_str(line); + result.push('\n'); + } + } + + result +} + +pub fn highlight_env(content: &str) -> String { + let lines: Vec<&str> = content.lines().collect(); + let mut result = String::new(); + + for line in lines { + let trimmed = line.trim(); + + if trimmed.is_empty() || trimmed.starts_with('#') { + result.push_str(&format!("{}\n", line.gray())); + } else if let Some(eq_idx) = trimmed.find('=') { + let key = &trimmed[..eq_idx].trim(); + let value = &trimmed[eq_idx + 1..].trim(); + result.push_str(&format!("{}", key.cyan().bold())); + result.push_str("="); + result.push_str(&format!("{}\n", value.green().to_string())); + } else { + result.push_str(line); + result.push('\n'); + } + } + + result +}