use crate::{
ContentHash,
Ident,
connect::lsp::ClientKind,
database::{
HasPartition,
Partition,
PartitionKey,
Partitions,
partitions::HandleEntry,
},
record::{
Record,
hash_record,
},
};
pub struct Clients;
impl PartitionKey for Clients {
const KEY: Ident = Ident::new("laburnum::clients");
}
impl Partition for Clients {
type Record = ClientRecord;
type IndexEntry = HandleEntry<Self>;
type SortKey = ClientSortKey;
fn index_entry_from_handle(
handle: crate::database::RecordHandle<Self>,
) -> Self::IndexEntry {
HandleEntry::new(handle)
}
}
#[derive(Debug, Clone, Hash)]
pub enum ClientRecord {
Connection {
client_id: u64,
kind: ClientKind,
},
Subscription {
client_id: u64,
topic: String,
},
}
impl Record for ClientRecord {
fn content_hash(&self) -> ContentHash {
hash_record(self)
}
}
impl bluegum::Bluegum for ClientRecord {
fn node(&self, b: &mut bluegum::Builder) {
match self {
ClientRecord::Connection { client_id, kind } => {
b.name("ClientRecord::Connection")
.field("client_id", client_id)
.field("kind", format!("{kind:?}"));
}
ClientRecord::Subscription { client_id, topic } => {
b.name("ClientRecord::Subscription")
.field("client_id", client_id)
.field("topic", topic);
}
}
}
}
impl bluegum::BluegumWithState<dyn crate::SpanResolver> for ClientRecord {}
#[derive(Debug, Clone)]
pub enum ClientSortKey {
Connection { client_id: u64 },
Subscription { client_id: u64, topic: String },
All,
ConnectionPrefix,
SubscriptionPrefix,
ClientPrefix { client_id: u64 },
}
impl std::fmt::Display for ClientSortKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
| Self::Connection { client_id } => write!(f, "conn|{:020}", client_id),
| Self::Subscription { client_id, topic } => {
write!(f, "sub|{:020}|{}", client_id, topic)
},
| Self::All => Ok(()),
| Self::ConnectionPrefix => write!(f, "conn|"),
| Self::SubscriptionPrefix => write!(f, "sub|"),
| Self::ClientPrefix { client_id } => write!(f, "sub|{:020}|", client_id),
}
}
}
use crate::database::chunk::RecordWriter;
pub trait ClientWriteExt<P: Partitions> {
fn write_client_connection(&mut self, client_id: u64, kind: ClientKind)
where
P::Stores: HasPartition<Clients>;
fn write_client_subscription(&mut self, client_id: u64, topic: String)
where
P::Stores: HasPartition<Clients>;
}
impl<P: Partitions> ClientWriteExt<P> for RecordWriter<P> {
fn write_client_connection(&mut self, client_id: u64, kind: ClientKind)
where
P::Stores: HasPartition<Clients>,
{
let sort_key = ClientSortKey::Connection { client_id };
let record = ClientRecord::Connection { client_id, kind };
self.insert::<Clients, _>(sort_key, record);
}
fn write_client_subscription(&mut self, client_id: u64, topic: String)
where
P::Stores: HasPartition<Clients>,
{
let sort_key = ClientSortKey::Subscription {
client_id,
topic: topic.clone(),
};
let record = ClientRecord::Subscription { client_id, topic };
self.insert::<Clients, _>(sort_key, record);
}
}