laburnum 1.17.3

An LSP framework for building language servers and compilers, powered by an incremental query tree with content-addressed storage, task-based dataflow, and parallel queries.
// Copyright Two Neutron Stars Incorporated and contributors
// SPDX-License-Identifier: BlueOak-1.0.0

use {
  crate::{
    ContentHash,
    database::{ContentAddressedStorage, Partitions},
  },
  std::sync::Arc,
};

pub(crate) struct RecordMetadata<P: Partitions> {
  pub(crate) partition_key: crate::SpannedIdent,
  pub(crate) sort_key: P::SortKey,
  pub(crate) content_hash: ContentHash,
}

impl<P: Partitions> Clone for RecordMetadata<P> {
  fn clone(&self) -> Self {
    Self {
      partition_key: self.partition_key,
      sort_key: self.sort_key.clone(),
      content_hash: self.content_hash,
    }
  }
}

impl<P: Partitions> std::fmt::Debug for RecordMetadata<P> {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    // The sort key has no string/Debug form (ADR0011).
    f.debug_struct("RecordMetadata")
      .field("partition_key", &self.partition_key)
      .field("content_hash", &self.content_hash)
      .finish_non_exhaustive()
  }
}

/// Results from a query builder execution.
///
/// Contains resolved CAS records matching the query. Use `iter()` to
/// iterate over the resolved `P::RecordRef` values, or `len()`/`is_empty()`
/// to check result count.
///
/// For typed index entry access (returning `Part::IndexEntry` directly),
/// use [`QueryClient::index_get`] or [`QueryClient::index_range`] instead.
#[derive(Debug)]
pub struct QueryResults<P: Partitions> {
  pub(crate) records: Vec<RecordMetadata<P>>,
  pub(crate) global_store: Arc<ContentAddressedStorage<P>>,
}

impl<P: Partitions> QueryResults<P> {
  pub(crate) fn new(
    records: Vec<RecordMetadata<P>>,
    global_store: Arc<ContentAddressedStorage<P>>,
  ) -> Self {
    Self {
      records,
      global_store,
    }
  }

  pub(crate) fn get(
    &self,
    record: &RecordMetadata<P>,
  ) -> Option<P::RecordRef<'_>> {
    self
      .global_store
      .get_any(record.partition_key, record.content_hash)
  }

  pub(crate) fn records(&self) -> &[RecordMetadata<P>] {
    &self.records
  }

  /// Public iterator - yields only resolved records (no metadata).
  pub fn iter(&self) -> impl Iterator<Item = P::RecordRef<'_>> {
    self.records.iter().filter_map(|meta| {
      self
        .global_store
        .get_any(meta.partition_key, meta.content_hash)
    })
  }

  pub fn is_empty(&self) -> bool {
    self.records.is_empty()
  }

  pub fn len(&self) -> usize {
    self.records.len()
  }
}

impl<P: Partitions> Clone for QueryResults<P> {
  fn clone(&self) -> Self {
    Self {
      records: self.records.clone(),
      global_store: Arc::clone(&self.global_store),
    }
  }
}