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