radicle-feed 0.3.1

A feed service for Radicle
Documentation
use std::fmt;
use std::future::Future;

use radicle::cob::{ObjectId, TypeName};
use radicle::git::Oid;
use radicle::prelude::RepoId;

use crate::entry::{OperationEntry, TimelineEntry};
use crate::radicle_extra::sql;

/// Trait for abstracting storage operations used by the rad-feed library.
/// Consumers can implement this trait to provide their own storage backend.
pub trait FeedStorage {
    type Error: snafu::Error + 'static;

    /// Get the last processed operation ID for a specific repository and COB (Collaborative Object)
    fn get_last_processed_operation(
        &self,
        rid: &RepoId,
        cob_id: &ObjectId,
        typename: &TypeName,
    ) -> impl Future<Output = Result<Option<sql::Oid>, Self::Error>>;

    fn insert_timeline_entry(
        &mut self,
        entry: &TimelineEntry,
    ) -> impl Future<Output = Result<(), Self::Error>>;

    /// Check if an operation already exists in storage (for duplicate prevention)
    fn operation_exists(
        &self,
        operation_id: &Oid,
    ) -> impl Future<Output = Result<bool, Self::Error>>;

    /// Insert a batch of operations entries into storage
    fn insert_batch(
        &mut self,
        entries: &[OperationEntry],
    ) -> impl Future<Output = Result<(), Self::Error>>;

    /// Get statistics about stored data (optional, used for debugging/monitoring)
    fn get_stats(&self) -> impl Future<Output = Result<StorageStats, Self::Error>>;
}

/// Statistics about the storage backend
#[derive(Debug, Default)]
pub struct StorageStats {
    pub total_operations: u64,
    pub operations_by_type: std::collections::HashMap<String, u64>,
    pub tracked_objects: u64,
}

impl fmt::Display for StorageStats {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        writeln!(f, "=== Storage Statistics ===")?;
        writeln!(f, "Total operations: {}", self.total_operations)?;

        for (kind, count) in &self.operations_by_type {
            writeln!(f, "{}: {}", kind, count)?;
        }

        writeln!(f, "Tracked objects: {}", self.tracked_objects)?;
        Ok(())
    }
}

#[cfg(feature = "postgres")]
pub mod postgres;