sql_cli/data/
csv_fixes.rs1use std::collections::HashMap;
4
5pub fn needs_quoting(column_name: &str) -> bool {
7 column_name.contains(' ')
8 || column_name.contains('-')
9 || column_name.contains('.')
10 || column_name.contains('(')
11 || column_name.contains(')')
12 || column_name.contains('[')
13 || column_name.contains(']')
14 || column_name.contains('"')
15 || column_name.contains('\'')
16}
17
18pub fn quote_if_needed(column_name: &str) -> String {
20 if needs_quoting(column_name) {
21 format!("\"{}\"", column_name.replace('"', "\"\""))
22 } else {
23 column_name.to_string()
24 }
25}
26
27pub fn build_column_lookup(headers: &[String]) -> HashMap<String, String> {
30 let mut lookup = HashMap::new();
31 for header in headers {
32 lookup.insert(header.to_lowercase(), header.clone());
33 }
34 lookup
35}
36
37pub fn find_column_case_insensitive<'a>(
39 obj: &'a serde_json::Map<String, serde_json::Value>,
40 column_name: &str,
41 lookup: &HashMap<String, String>,
42) -> Option<(&'a String, &'a serde_json::Value)> {
43 if let Some(value) = obj.get_key_value(column_name) {
45 return Some(value);
46 }
47
48 if let Some(actual_name) = lookup.get(&column_name.to_lowercase()) {
50 obj.get_key_value(actual_name)
51 } else {
52 let column_unquoted = column_name.trim_matches('"');
54 for (key, value) in obj {
55 if key == column_unquoted || key.to_lowercase() == column_unquoted.to_lowercase() {
56 return Some((key, value));
57 }
58 }
59 None
60 }
61}
62
63pub fn parse_column_name(column: &str) -> &str {
65 column.trim().trim_matches('"').trim_matches('\'')
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_needs_quoting() {
74 assert!(!needs_quoting("City"));
75 assert!(!needs_quoting("customer_id"));
76 assert!(needs_quoting("Phone 1"));
77 assert!(needs_quoting("Customer-ID"));
78 assert!(needs_quoting("Price ($)"));
79 }
80
81 #[test]
82 fn test_quote_if_needed() {
83 assert_eq!(quote_if_needed("City"), "City");
84 assert_eq!(quote_if_needed("Phone 1"), "\"Phone 1\"");
85 assert_eq!(quote_if_needed("Has\"Quote"), "\"Has\"\"Quote\"");
86 }
87}