use amethystate_core::Source;
use amethystate_core::path::StorePath;
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SubscriptionId(u64);
impl SubscriptionId {
pub fn next() -> Self {
static NEXT: AtomicU64 = AtomicU64::new(1);
Self(NEXT.fetch_add(1, Ordering::Relaxed))
}
}
pub type StoreCallback =
Arc<dyn Fn(&StoreEvent) -> crate::store::StorageResult<()> + Send + Sync + 'static>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StoreOp {
Set,
Delete,
DeletePrefix,
}
#[derive(Debug, Clone)]
pub struct StoreEvent {
pub path: StorePath,
pub op: StoreOp,
pub old: Option<Vec<u8>>,
pub new: Option<Vec<u8>>,
pub source: Source,
pub at: u64,
pub judged: bool,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Writer {
pub handle: Option<uuid::Uuid>,
pub judged: bool,
}
impl Writer {
pub fn judged(handle: Option<uuid::Uuid>) -> Self {
Self {
handle,
judged: true,
}
}
}
impl From<Option<uuid::Uuid>> for Writer {
fn from(handle: Option<uuid::Uuid>) -> Self {
Self {
handle,
judged: false,
}
}
}
impl StoreEvent {
pub fn is_external_edit(&self) -> bool {
matches!(self.source, Source::Disk | Source::AnotherPage)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SubscriptionKind {
Any,
ExactPath(StorePath),
Prefix(StorePath),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum CodecFormat {
#[cfg(any(feature = "redb", feature = "memory"))]
MessagePack,
#[cfg(any(feature = "json", feature = "localstorage"))]
Json,
#[cfg(feature = "sqlite")]
SonicJson,
#[cfg(feature = "toml")]
Toml,
#[cfg(feature = "ron")]
Ron,
}
#[derive(Clone)]
pub struct SubscriptionEntry {
pub id: SubscriptionId,
pub kind: SubscriptionKind,
pub callback: StoreCallback,
}
pub struct StoreSubscription {
store: crate::Store,
id: SubscriptionId,
}
impl StoreSubscription {
pub(crate) fn new(store: crate::Store, id: SubscriptionId) -> Self {
Self { store, id }
}
pub fn id(&self) -> SubscriptionId {
self.id
}
pub(crate) fn store(&self) -> &crate::Store {
&self.store
}
}
impl Drop for StoreSubscription {
fn drop(&mut self) {
self.store.unsubscribe(self.id);
}
}