use {
laburnum::{
database::{
Partition,
PartitionKey,
storage::{
PartitionsBuilder,
RecordStorage,
},
},
hash::ContentHasher,
record::{
LaburnumRecord,
Record,
},
Ident,
},
serde::Serialize,
std::hash::Hash,
};
#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
pub struct TestIndex(usize);
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize)]
pub enum TestRecordData {
Test { value: String, count: usize },
Laburnum(LaburnumRecord),
}
impl TestRecordData {
pub fn new(value: String, count: usize) -> Self {
Self::Test { value, count }
}
}
impl Record for TestRecordData {
fn content_hash(&self) -> laburnum::ContentHash {
laburnum::record::hash_record(self)
}
}
impl<P: laburnum::database::storage::Partitions> laburnum::record::CollectReferences<P>
for TestRecordData
{
}
impl laburnum::record::LaburnumRecordRef for &TestRecordData {
fn as_laburnum_record(&self) -> Option<&LaburnumRecord> {
match self {
| TestRecordData::Laburnum(lr) => Some(lr),
| _ => None,
}
}
fn serialize_with_source_cache<P, T, Ser>(
&self,
_source_cache: &laburnum::source::SourceCache<P, T>,
serializer: Ser,
) -> Result<Ser::Ok, Ser::Error>
where
P: laburnum::database::storage::Partitions,
T: laburnum::protocol::lsp::LanguageServer<P>,
Ser: serde::Serializer,
{
serde::Serialize::serialize(self, serializer)
}
}
impl From<LaburnumRecord> for TestRecordData {
fn from(record: LaburnumRecord) -> Self {
TestRecordData::Laburnum(record)
}
}
impl bluegum::Bluegum for TestRecordData {
fn node(&self, b: &mut bluegum::Builder) {
match self {
TestRecordData::Test { value, count } => {
b.name("TestRecordData::Test")
.field("value", value)
.field("count", count);
},
TestRecordData::Laburnum(lr) => {
b.name("TestRecordData::Laburnum");
b.add_node("record", lr);
},
}
}
}
impl bluegum::BluegumWithState<dyn laburnum::SpanResolver> for TestRecordData {}
#[allow(dead_code)]
#[derive(Debug)]
pub struct TestStorage {
records: Vec<TestRecordData>,
}
impl RecordStorage for TestStorage {
type Builder = TestStorageBuilder;
type Index = TestIndex;
type RecordRef<'a> = &'a TestRecordData;
fn get(&self, idx: &Self::Index) -> Option<Self::RecordRef<'_>> {
self.records.get(idx.0)
}
fn hash_contents(&self, hasher: &mut ContentHasher) {
for record in &self.records {
match record {
| TestRecordData::Test { value, count } => {
hasher.update(value.as_bytes());
hasher.update(&count.to_le_bytes());
},
| TestRecordData::Laburnum(lr) => {
hasher.update(&(lr as *const LaburnumRecord as usize).to_le_bytes());
},
}
}
}
}
#[allow(dead_code)]
#[derive(Default)]
pub struct TestStorageBuilder {
records: Vec<TestRecordData>,
}
impl PartitionsBuilder for TestStorageBuilder {
type Record = TestRecordData;
type Storage = TestStorage;
fn push(&mut self, record: Self::Record) -> TestIndex {
let idx = TestIndex(self.records.len());
self.records.push(record);
idx
}
fn build(self) -> Self::Storage {
TestStorage {
records: self.records,
}
}
}
pub struct TestPartition;
impl PartitionKey for TestPartition {
const KEY: Ident = Ident::new("test::records");
}
impl Partition for TestPartition {
type Record = TestRecordData;
type IndexEntry = laburnum::database::partitions::HandleEntry<Self>;
type SortKey = String;
fn index_entry_from_handle(
handle: laburnum::database::RecordHandle<Self>,
) -> Self::IndexEntry {
laburnum::database::partitions::HandleEntry::new(handle)
}
}
laburnum::define_partitions! {
Test,
partitions = [Test,],
}