vstorage 0.10.0

Common API for various icalendar/vcard storages.
Documentation
// Copyright 2024-2026 Hugo Osvaldo Barrera
//
// SPDX-License-Identifier: EUPL-1.2

//! Monitor a storage for changes as they occur.
use futures_util::future::BoxFuture;

use crate::{Href, property::Property};

/// Monitors a storage for live events.
///
/// Implementations shall yield [`Event::Storage`] whenever changes have happened, but the
/// underlying interfaces don't provide enough information to determine which items changed.
/// This includes (but is not limited to) disconnection or buffer full.
///
/// Monitors MUST yield events for changes that have occurred since the last access to this
/// storage. If this is unknown (e.g.: no state is preserved between executions), an
/// [`Event::Storage`] must be emitted immediately upon the first call to
/// [`StorageMonitor::next_event`].
///
/// # See also
///
/// - [[`Storage::monitor`][crate::base::Storage::monitor]
pub trait StorageMonitor: Send {
    /// Return the next event on this storage.
    ///
    /// Returns a future which resolves the next change event, or `None` when monitoring cannot
    /// continue. Transient errors are resolved internally, so `None` generally implies a fatal
    /// error condition.
    ///
    /// # Cancel safety
    ///
    /// Implementations MUST be cancel safe. If the returned future is dropped before completion, the
    /// next call MUST return the following event without dropping any events.
    fn next_event(&mut self) -> BoxFuture<'_, Option<Event>>;
}

/// Event yielded when monitoring a storage.
///
/// Returned by [`StorageMonitor::next_event`]
#[derive(Debug, PartialEq)]
pub enum Event {
    /// No details are known; only that something has changed.
    ///
    /// Indicates that something has changed, but there is insufficient information to determine
    /// what changed. The entire storage should be re-scanned to manually find changes.
    Storage,
    /// Collection changed.
    Collection(Href, EventKind),
    /// Item changed. First `Href` is collection href, second is item href.
    Item(Href, Href, EventKind),
    /// Collection property changed.
    Property(Href, Property, EventKind),
}

/// Kind of event.
///
/// See: [`Event`].
#[derive(Debug, PartialEq)]
pub enum EventKind {
    /// New element was created or existing one was modified.
    Change,
    /// Previously seen element has been deleted.
    Delete,
}