use std::collections::HashMap;
use std::path::{Path, PathBuf};
use crate::identifier::{Identifier, QualifiedName};
use crate::ir::catalog::Catalog;
use crate::parse::SourceLocation;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ObjectKey {
Schema(Identifier),
Table(QualifiedName),
Index(QualifiedName),
Sequence(QualifiedName),
}
impl ObjectKey {
pub const fn kind_name(&self) -> &'static str {
match self {
Self::Schema(_) => "schema",
Self::Table(_) => "table",
Self::Index(_) => "index",
Self::Sequence(_) => "sequence",
}
}
pub const fn kind_plural(&self) -> &'static str {
match self {
Self::Schema(_) => "schemas",
Self::Table(_) => "tables",
Self::Index(_) => "indexes",
Self::Sequence(_) => "sequences",
}
}
pub const fn schema(&self) -> &Identifier {
match self {
Self::Schema(s) => s,
Self::Table(q) | Self::Index(q) | Self::Sequence(q) => &q.schema,
}
}
pub const fn bare_name(&self) -> &Identifier {
match self {
Self::Schema(s) => s,
Self::Table(q) | Self::Index(q) | Self::Sequence(q) => &q.name,
}
}
}
impl std::fmt::Display for ObjectKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Schema(s) => write!(f, "schema:{s}"),
Self::Table(q) => write!(f, "table:{q}"),
Self::Index(q) => write!(f, "index:{q}"),
Self::Sequence(q) => write!(f, "sequence:{q}"),
}
}
}
#[derive(Debug, Clone)]
pub struct SourceTree {
pub catalog: Catalog,
pub object_locations: HashMap<ObjectKey, SourceLocation>,
}
impl SourceTree {
pub const fn new(
catalog: Catalog,
object_locations: HashMap<ObjectKey, SourceLocation>,
) -> Self {
Self {
catalog,
object_locations,
}
}
pub fn objects(&self) -> impl Iterator<Item = &ObjectKey> {
self.object_locations.keys()
}
pub fn file_of(&self, key: &ObjectKey) -> Option<&Path> {
self.object_locations.get(key).map(|l| l.file.as_path())
}
pub fn objects_by_file(&self) -> HashMap<PathBuf, Vec<ObjectKey>> {
let mut out: HashMap<PathBuf, Vec<ObjectKey>> = HashMap::new();
for (k, loc) in &self.object_locations {
out.entry(loc.file.clone()).or_default().push(k.clone());
}
for v in out.values_mut() {
v.sort_by_key(ToString::to_string);
}
out
}
}