use {
crate::core::{Ident, SymbolPath, Value},
laburnum::{
ContentHash,
database::{RecordHandle, partitions::IndexEntry},
record::CollectReferences,
},
std::hash::Hash,
};
use super::symbols::Symbols;
#[derive(Debug, Clone)]
pub struct SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
pub span: laburnum::Span,
pub symbol: RecordHandle<Symbols<V, I, P>>,
}
impl<V, I, P> Copy for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
}
impl<V, I, P> Hash for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.span.hash(state);
self.symbol.hash(state);
}
}
impl<V, I, P> PartialEq for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn eq(&self, other: &Self) -> bool {
self.span == other.span && self.symbol == other.symbol
}
}
impl<V, I, P> Eq for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
}
impl<V, I, P> SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
pub fn new(
span: laburnum::Span,
symbol: RecordHandle<Symbols<V, I, P>>,
) -> Self {
Self { span, symbol }
}
}
impl<V, I, P> IndexEntry for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn primary_hash(&self) -> Option<ContentHash> {
Some(self.symbol.content_hash())
}
}
impl<V, I, P> laburnum::database::partitions::IndexedEntry
for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn content_hash(&self) -> ContentHash {
self.symbol.content_hash()
}
}
impl<V, I, P> bluegum::Bluegum for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn node(&self, b: &mut bluegum::Builder) {
b.name("SymbolEntry")
.field("span", self.span)
.field("symbol", self.symbol.content_hash());
}
}
impl<V, I, P> bluegum::BluegumWithState<dyn laburnum::SpanResolver>
for SymbolEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn node_with_state(
&self,
b: &mut bluegum::Builder,
_state: &dyn laburnum::SpanResolver,
) {
b.name("SymbolEntry")
.field("symbol", self.symbol.content_hash());
}
}
impl<Ps, V, I, P> CollectReferences<Ps> for SymbolEntry<V, I, P>
where
Ps: laburnum::database::storage::Partitions,
Ps::Stores: laburnum::database::partitions::HasPartition<Symbols<V, I, P>>,
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn collect_references<R: laburnum::record::References<Ps>>(
&self,
refs: &mut R,
) {
refs.add(self.symbol);
}
}
#[derive(Debug, Clone, Hash)]
pub struct ResolutionEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
pub target_path: P,
pub target: RecordHandle<Symbols<V, I, P>>,
}
impl<V, I, P> ResolutionEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
pub fn new(target_path: P, target: RecordHandle<Symbols<V, I, P>>) -> Self {
Self {
target_path,
target,
}
}
}
impl<V, I, P> IndexEntry for ResolutionEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn primary_hash(&self) -> Option<ContentHash> {
Some(self.target.content_hash())
}
}
impl<V, I, P> laburnum::database::partitions::IndexedEntry
for ResolutionEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn content_hash(&self) -> ContentHash {
self.target.content_hash()
}
}
impl<V, I, P> bluegum::Bluegum for ResolutionEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn node(&self, b: &mut bluegum::Builder) {
b.name("ResolutionEntry")
.field("target_path", format!("{:?}", self.target_path))
.field("target", self.target.content_hash());
}
}
impl<V, I, P> bluegum::BluegumWithState<dyn laburnum::SpanResolver>
for ResolutionEntry<V, I, P>
where
V: Value<I>,
I: Ident,
P: SymbolPath,
{
}
impl<Ps, V, I, P> CollectReferences<Ps> for ResolutionEntry<V, I, P>
where
Ps: laburnum::database::storage::Partitions,
Ps::Stores: laburnum::database::partitions::HasPartition<Symbols<V, I, P>>,
V: Value<I>,
I: Ident,
P: SymbolPath,
{
fn collect_references<R: laburnum::record::References<Ps>>(
&self,
refs: &mut R,
) {
refs.add(self.target);
}
}