Skip to main content

rustapi_jobs/
job.rs

1use crate::error::Result;
2use async_trait::async_trait;
3use serde::{de::DeserializeOwned, Serialize};
4use std::fmt::Debug;
5
6/// Context passed to job execution
7#[derive(Debug, Clone)]
8pub struct JobContext {
9    pub job_id: String,
10    pub attempt: u32,
11    pub created_at: chrono::DateTime<chrono::Utc>,
12}
13
14/// A job that can be executed
15#[async_trait]
16pub trait Job: Send + Sync + 'static {
17    /// The job name/type
18    const NAME: &'static str;
19
20    /// The data required by the job
21    type Data: Serialize + DeserializeOwned + Send + Sync + Debug;
22
23    /// Execute the job
24    async fn execute(&self, ctx: JobContext, data: Self::Data) -> Result<()>;
25}
26
27/// A type-erased job handler
28#[async_trait]
29pub trait JobHandler: Send + Sync {
30    async fn handle(&self, ctx: JobContext, data: serde_json::Value) -> Result<()>;
31}
32
33#[async_trait]
34impl<J: Job> JobHandler for J {
35    async fn handle(&self, ctx: JobContext, data: serde_json::Value) -> Result<()> {
36        let data: J::Data = serde_json::from_value(data)?;
37        self.execute(ctx, data).await
38    }
39}