laburnum 1.17.0

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.
Documentation
// Copyright Two Neutron Stars Incorporated and contributors
// SPDX-License-Identifier: BlueOak-1.0.0

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

#[derive(Clone, Debug, Serialize)]
pub(crate) struct RecordMetadata {
  pub(crate) partition_key: Ident,
  pub(crate) sort_key:      String,
  pub(crate) content_hash:  ContentHash,
}

/// 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>,
  pub(crate) global_store: Arc<ContentAddressedStorage<P>>,
}

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

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

  pub(crate) fn records(&self) -> &[RecordMetadata] {
    &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)
    })
  }

  /// Internal iterator - yields metadata + record (for use within laburnum).
  pub(crate) fn iter_with_metadata(&self) -> impl Iterator<Item = (&RecordMetadata, Option<P::RecordRef<'_>>)> {
    self.records.iter().map(|meta| {
      let record = self.global_store.get_any(meta.partition_key, meta.content_hash);
      (meta, record)
    })
  }

  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),
    }
  }
}