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>;