use sealmap_mermaid::Ident;
use sealmap_model::{Codebase, SymbolId, SymbolKind};
use crate::{CorpusOptions, ExternalLanes};
pub(crate) fn ident(id: &SymbolId) -> Ident {
Ident::from_symbol(id)
}
pub(crate) fn assert_unique_idents(cb: &Codebase) {
let mut seen: std::collections::BTreeMap<Ident, &SymbolId> = std::collections::BTreeMap::new();
let ids = cb.symbols.keys().chain(cb.relations.iter().flat_map(|r| [&r.from, &r.to]));
for id in ids {
if let Some(prev) = seen.insert(ident(id), id) {
assert!(prev == id, "diagram id collision: `{prev}` and `{id}` both map to `{}`", ident(id));
}
}
}
pub(crate) struct Lane {
pub id: SymbolId,
pub alias: String,
pub prefix: String,
pub external: bool,
}
pub(crate) fn lane_of(cb: &Codebase, target: &SymbolId, opts: &CorpusOptions) -> Lane {
if cb.is_internal(target) {
let owner = cb.owner_of(target).unwrap_or_else(|| target.clone());
return Lane { alias: alias_for(cb, &owner), id: owner, prefix: String::new(), external: false };
}
if target.is_unresolved() {
return Lane { id: SymbolId::unresolved(""), alias: "?".into(), prefix: String::new(), external: true };
}
if let Some(parent) = target.parent() {
if cb.is_internal(&parent) {
return Lane { alias: alias_for(cb, &parent), id: parent, prefix: String::new(), external: false };
}
}
let segs = target.names();
match opts.external_lanes {
ExternalLanes::CrateRoot => {
let root = segs[0].clone();
let prefix = if segs.len() > 2 { format!("{}::", segs[segs.len() - 2]) } else { String::new() };
let id = SymbolId::path([root.as_ref()]).unwrap_or_else(|_| SymbolId::unresolved(""));
Lane { id, alias: root.into_owned(), prefix, external: true }
}
ExternalLanes::Owner => {
let owner = target.parent().unwrap_or_else(|| target.clone());
Lane { alias: owner.name().into_owned(), id: owner, prefix: String::new(), external: true }
}
}
}
pub(crate) fn alias_for(cb: &Codebase, id: &SymbolId) -> String {
match cb.symbol(id) {
Some(s) if s.kind == SymbolKind::Module => format!("{} mod", s.name),
Some(s) => s.name.clone(),
None => id.name().into_owned(),
}
}