Skip to main content

nest_rs_queue/
processor.rs

1//! Job + Processor: the user-facing types every backend agrees on.
2
3use async_trait::async_trait;
4use nest_rs_core::Container;
5use serde::Serialize;
6use serde::de::DeserializeOwned;
7
8/// JSON-round-trippable + Clone (retry keeps a copy) + cross-task safe.
9///
10/// The marker is intentionally minimal — backends communicate jobs as JSON on
11/// the wire (the open contract), so every `Job` is `Serialize +
12/// DeserializeOwned`. Backends that prefer a binary codec internally still
13/// negotiate this JSON shape at the macro/inventory boundary.
14pub trait Job: Serialize + DeserializeOwned + Clone + Send + Sync + Unpin + 'static {}
15impl<T> Job for T where T: Serialize + DeserializeOwned + Clone + Send + Sync + Unpin + 'static {}
16
17/// A returned `Err` marks the job failed; the backend retries up to the
18/// `#[process(retries = N)]` budget.
19#[async_trait]
20pub trait Processor: Send + Sync + 'static {
21    /// The job payload type this processor consumes.
22    type Job: Job;
23
24    /// Handle one job; returning `Err` fails it for the backend to retry.
25    async fn process(&self, job: Self::Job) -> anyhow::Result<()>;
26}
27
28/// Queue analog of `#[injectable]`'s `from_container`, expressed as a trait so
29/// a backend can build any processor generically from the container.
30pub trait FromContainer: Sized {
31    /// Build the processor by resolving its `#[inject]` dependencies.
32    fn from_container(container: &Container) -> Self;
33}