laburnum 1.17.2

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::{Ident, database::storage::Partitions, hash::ident::IdentHasher},
  std::hash::{Hash, Hasher},
};

/// An opaque reference to a record by its index key (partition_key + sort_key).
///
/// Unlike `RecordHandle<P>` which references a CAS record by content hash,
/// `RecordKey` references a record by its position in the index. The sort key
/// is the typed [`Partitions::SortKey`] sum type (ADR0011) — never a string.
///
/// External consumers fetch the record with `get_record()`, pattern-match the
/// typed `sort_key()` to read structured fields, or derive a deterministic hash
/// with `key_ident()`. There is no string projection of the key.
pub struct RecordKey<P: Partitions> {
  partition_key: Ident,
  sort_key: P::SortKey,
}

impl<P: Partitions> RecordKey<P> {
  pub(crate) fn new(partition_key: Ident, sort_key: P::SortKey) -> Self {
    Self {
      partition_key,
      sort_key,
    }
  }

  /// Returns the partition key.
  pub(crate) fn partition_key(&self) -> Ident {
    self.partition_key
  }

  /// Returns the typed sort key.
  ///
  /// Pattern-match the variant to read structured fields. There is deliberately
  /// no string form (ADR0011); to render for humans, use
  /// [`PartitionSortKey::resolve`](crate::database::partitions::PartitionSortKey::resolve)
  /// with a resolver.
  pub fn sort_key(&self) -> &P::SortKey {
    &self.sort_key
  }

  /// Fetch the record from the database using a query client.
  pub async fn get_record(
    &self,
    query_client: &mut crate::database::query::QueryClient<P>,
  ) -> crate::database::query_results::QueryResults<P> {
    query_client
      .get_record(self.partition_key, self.sort_key.clone())
      .await
  }

  /// Derive a deterministic `Ident` from the key's structural content.
  ///
  /// Hashes the typed key via its `Hash` impl — no string round-trip.
  pub fn key_ident(&self) -> Ident {
    let mut hasher = IdentHasher::new();
    self.partition_key.hash(&mut hasher);
    self.sort_key.hash(&mut hasher);
    Ident::from_hash(hasher.finish())
  }
}

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

impl<P: Partitions> PartialEq for RecordKey<P> {
  fn eq(&self, other: &Self) -> bool {
    self.partition_key == other.partition_key && self.sort_key == other.sort_key
  }
}

impl<P: Partitions> Eq for RecordKey<P> {}

impl<P: Partitions> Hash for RecordKey<P> {
  fn hash<H: Hasher>(&self, state: &mut H) {
    self.partition_key.hash(state);
    self.sort_key.hash(state);
  }
}

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