pgevolve_core/lint/
source_tree.rs1use std::collections::HashMap;
7use std::path::{Path, PathBuf};
8
9use crate::identifier::{Identifier, QualifiedName};
10use crate::ir::catalog::Catalog;
11use crate::parse::SourceLocation;
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub enum ObjectKey {
16 Schema(Identifier),
18 Table(QualifiedName),
20 Index(QualifiedName),
22 Sequence(QualifiedName),
24}
25
26impl ObjectKey {
27 pub const fn kind_name(&self) -> &'static str {
29 match self {
30 Self::Schema(_) => "schema",
31 Self::Table(_) => "table",
32 Self::Index(_) => "index",
33 Self::Sequence(_) => "sequence",
34 }
35 }
36
37 pub const fn kind_plural(&self) -> &'static str {
39 match self {
40 Self::Schema(_) => "schemas",
41 Self::Table(_) => "tables",
42 Self::Index(_) => "indexes",
43 Self::Sequence(_) => "sequences",
44 }
45 }
46
47 pub const fn schema(&self) -> &Identifier {
51 match self {
52 Self::Schema(s) => s,
53 Self::Table(q) | Self::Index(q) | Self::Sequence(q) => &q.schema,
54 }
55 }
56
57 pub const fn bare_name(&self) -> &Identifier {
61 match self {
62 Self::Schema(s) => s,
63 Self::Table(q) | Self::Index(q) | Self::Sequence(q) => &q.name,
64 }
65 }
66}
67
68impl std::fmt::Display for ObjectKey {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 match self {
71 Self::Schema(s) => write!(f, "schema:{s}"),
72 Self::Table(q) => write!(f, "table:{q}"),
73 Self::Index(q) => write!(f, "index:{q}"),
74 Self::Sequence(q) => write!(f, "sequence:{q}"),
75 }
76 }
77}
78
79#[derive(Debug, Clone)]
81pub struct SourceTree {
82 pub catalog: Catalog,
84 pub object_locations: HashMap<ObjectKey, SourceLocation>,
87}
88
89impl SourceTree {
90 pub const fn new(
92 catalog: Catalog,
93 object_locations: HashMap<ObjectKey, SourceLocation>,
94 ) -> Self {
95 Self {
96 catalog,
97 object_locations,
98 }
99 }
100
101 pub fn objects(&self) -> impl Iterator<Item = &ObjectKey> {
103 self.object_locations.keys()
104 }
105
106 pub fn file_of(&self, key: &ObjectKey) -> Option<&Path> {
108 self.object_locations.get(key).map(|l| l.file.as_path())
109 }
110
111 pub fn objects_by_file(&self) -> HashMap<PathBuf, Vec<ObjectKey>> {
113 let mut out: HashMap<PathBuf, Vec<ObjectKey>> = HashMap::new();
114 for (k, loc) in &self.object_locations {
115 out.entry(loc.file.clone()).or_default().push(k.clone());
116 }
117 for v in out.values_mut() {
118 v.sort_by_key(ToString::to_string);
119 }
120 out
121 }
122}