use {
crate::ContentHash,
std::hash::{
Hash,
Hasher,
},
};
use crate::database::{
HasPartition, Partition, RecordHandle,
storage::Partitions,
};
pub trait References<P: Partitions> {
fn add<Part: Partition>(&mut self, handle: RecordHandle<Part>)
where
P::Stores: HasPartition<Part>;
}
pub trait CollectReferences<P: Partitions> {
fn collect_references<R: References<P>>(&self, _refs: &mut R) {
}
}
pub trait Record: Send + Sync {
fn content_hash(&self) -> ContentHash;
}
impl Record for () {
fn content_hash(&self) -> ContentHash {
ContentHash::new(&[])
}
}
impl<P: Partitions> CollectReferences<P> for () {}
pub fn hash_record<T: Hash>(value: &T) -> ContentHash {
let mut hasher = HashToContent::default();
value.hash(&mut hasher);
ContentHash::new(&hasher.0)
}
#[derive(Default)]
struct HashToContent(Vec<u8>);
impl Hasher for HashToContent {
fn finish(&self) -> u64 {
0
}
fn write(&mut self, bytes: &[u8]) {
self.0.extend_from_slice(bytes);
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Serialize)]
pub enum LaburnumRecord {
WorkspaceConfig { value: String },
}
impl bluegum::Bluegum for LaburnumRecord {
fn node(&self, b: &mut bluegum::Builder) {
match self {
LaburnumRecord::WorkspaceConfig { value } => {
b.name("LaburnumRecord::WorkspaceConfig")
.field("value", value);
}
}
}
}
impl bluegum::BluegumWithState<dyn crate::SpanResolver> for LaburnumRecord {}
#[macro_export]
macro_rules! define_record_enum {
(
$vis:vis enum $name:ident {
$($variant:ident),* $(,)?
}
) => {
$crate::paste::paste! {
#[derive(Clone)]
$vis enum [<$name Record>] {
$(
$variant([<$variant Record>]),
)*
}
#[derive(Clone, Copy)]
$vis enum [<$name RecordRef>]<'a> {
$(
$variant(&'a [<$variant Record>]),
)*
}
impl [<$name Record>] {
pub fn as_ref(&self) -> [<$name RecordRef>]<'_> {
match self {
$(
| [<$name Record>]::$variant(inner) => [<$name RecordRef>]::$variant(inner),
)*
}
}
}
impl<'a> From<&'a [<$name Record>]> for [<$name RecordRef>]<'a> {
fn from(record: &'a [<$name Record>]) -> Self {
record.as_ref()
}
}
$(
impl From<[<$variant Record>]> for [<$name Record>] {
fn from(record: [<$variant Record>]) -> Self {
[<$name Record>]::$variant(record)
}
}
)*
}
};
}
pub trait SerializeWithSourceCache {
fn serialize_with_source_cache<P, T, Ser>(
&self,
source_cache: &crate::source::SourceCache<P, T>,
serializer: Ser,
) -> Result<Ser::Ok, Ser::Error>
where
P: crate::database::storage::Partitions,
T: crate::protocol::lsp::LanguageServer<P>,
Ser: serde::Serializer;
}
pub trait LaburnumRecordRef: serde::Serialize {
fn as_laburnum_record(&self) -> Option<&LaburnumRecord>;
fn as_dyn_diagnostic(
&self,
) -> Option<&dyn crate::partitions::diagnostics::DiagnosticRecord> {
None
}
fn as_document_symbol(
&self,
) -> Option<&dyn crate::partitions::document_symbols::DocumentSymbolRecord>
{
None
}
fn as_workspace_symbol(
&self,
) -> Option<&crate::protocol::lsp::WorkspaceSymbol> {
None
}
fn as_text_document_position(
&self,
) -> Option<
&dyn crate::partitions::text_document_position::TextDocumentPositionRecord,
> {
None
}
fn as_text_document_reference(
&self,
) -> Option<&dyn crate::partitions::text_document_references::TextDocumentReferenceRecord>
{
None
}
fn as_folding_range(
&self,
) -> Option<&dyn crate::partitions::document_folding_range::FoldingRangeRecord>
{
None
}
fn as_work_done_progress(
&self,
) -> Option<&dyn crate::partitions::work_done_progress::WorkDoneProgressRecord>
{
None
}
fn serialize_with_source_cache<P, T, Ser>(
&self,
source_cache: &crate::source::SourceCache<P, T>,
serializer: Ser,
) -> Result<Ser::Ok, Ser::Error>
where
P: crate::database::storage::Partitions,
T: crate::protocol::lsp::LanguageServer<P>,
Ser: serde::Serializer;
}