1use crate::error::{Result, SafeMigrateError};
2use crate::model::{IndexIdentity, TableIdentity};
3use squawk_syntax::ast::{self, AstNode};
4
5pub fn normalize_ident(ident: &str) -> String {
6 let ident = ident.trim();
7 if ident.starts_with('"') && ident.ends_with('"') && ident.len() >= 2 {
8 ident[1..ident.len() - 1].to_string()
9 } else {
10 ident.to_ascii_lowercase()
11 }
12}
13
14fn extract_segment_text(seg: &ast::PathSegment) -> String {
15 if let Some(name) = seg.name() {
16 if let Some(ident) = name.ident_token() {
17 return ident.text().to_string();
18 }
19 } else if let Some(name_ref) = seg.name_ref()
20 && let Some(ident) = name_ref.ident_token()
21 {
22 return ident.text().to_string();
23 }
24 seg.syntax().text().to_string()
25}
26
27pub fn extract_path_components(path: ast::Path) -> Result<(Option<String>, String)> {
28 let mut segments = Vec::new();
29 let mut current_path = Some(path);
30
31 while let Some(p) = current_path {
32 if let Some(seg) = p.segment() {
33 segments.push(extract_segment_text(&seg));
34 }
35 current_path = p.qualifier();
36 }
37 segments.reverse();
38
39 match segments.as_slice() {
40 [name] => Ok((None, normalize_ident(name))),
41 [schema, name] => Ok((Some(normalize_ident(schema)), normalize_ident(name))),
42 _ => Err(SafeMigrateError::Parse(format!(
43 "Unsupported identifier length (got {}): {}",
44 segments.len(),
45 segments.join(".")
46 ))),
47 }
48}
49
50pub fn extract_table_identity(path: ast::Path) -> Result<TableIdentity> {
51 let (schema, name) = extract_path_components(path)?;
52 Ok(TableIdentity { schema, name })
53}
54
55pub fn extract_index_identity(path: ast::Path) -> Result<IndexIdentity> {
56 let (schema, name) = extract_path_components(path)?;
57 Ok(IndexIdentity { schema, name })
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_normalize_ident_standard() {
66 assert_eq!(normalize_ident("Users"), "users");
68 assert_eq!(normalize_ident("CamelCaseTable"), "camelcasetable");
69 }
70
71 #[test]
72 fn test_normalize_ident_quoted() {
73 assert_eq!(normalize_ident("\"Users\""), "Users");
75 assert_eq!(normalize_ident("\"CamelCaseTable\""), "CamelCaseTable");
76 assert_eq!(
77 normalize_ident("\"weird-table-name!\""),
78 "weird-table-name!"
79 );
80 }
81}