Add source files: main, lib, cli, error, convert, highlight, validate, typescript
This commit is contained in:
196
src/highlight.rs
Normal file
196
src/highlight.rs
Normal file
@@ -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::<f64>().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
|
||||
}
|
||||
Reference in New Issue
Block a user