Skip to main content

atrg_feed/
handler.rs

1//! Feed handler type for producing feed skeletons.
2//!
3//! A [`FeedHandler`] is a function that takes a [`FeedRequest`] and the
4//! application state, returning a [`FeedSkeleton`] or an XRPC error.
5
6use std::future::Future;
7use std::pin::Pin;
8use std::sync::Arc;
9
10use atrg_core::state::AppState;
11use atrg_xrpc::XrpcError;
12
13use crate::types::FeedSkeleton;
14
15/// Parameters passed to a feed handler when a skeleton is requested.
16#[derive(Debug, Clone)]
17pub struct FeedRequest {
18    /// The full AT-URI of the feed being requested.
19    pub feed: String,
20    /// Pagination cursor from the client. `None` on the first page.
21    pub cursor: Option<String>,
22    /// Maximum number of items to return (already clamped to 1..=100).
23    pub limit: usize,
24    /// DID of the requesting user, if authenticated.
25    pub requester_did: Option<String>,
26}
27
28/// A boxed future returned by feed handlers.
29type FeedFuture = Pin<Box<dyn Future<Output = Result<FeedSkeleton, XrpcError>> + Send>>;
30
31/// A feed handler function.
32///
33/// Takes a [`FeedRequest`] and [`AppState`], returning a future that
34/// resolves to a [`FeedSkeleton`] or an [`XrpcError`].
35///
36/// Construct one by wrapping an async function with [`Arc`]:
37///
38/// ```rust,ignore
39/// let handler: FeedHandler = Arc::new(|req, state| {
40///     Box::pin(async move {
41///         Ok(FeedSkeleton { feed: vec![], cursor: None })
42///     })
43/// });
44/// ```
45pub type FeedHandler = Arc<dyn Fn(FeedRequest, AppState) -> FeedFuture + Send + Sync>;