agenda_rs/
lib.rs

1//! # Agenda RS
2//!
3//! A stateful, database-backed job queue for Rust, inspired by `AgendaJS`.
4//!
5//! # Example: Creating and Scheduling a Job
6//!
7//! This example demonstrates how to define a custom job with internal state,
8//! register it with the agenda, and schedule it for execution.
9//!
10//! ```rust,no_run
11//! use agenda_rs::prelude::*;
12//! use std::str::FromStr;
13//! use std::time::Duration;
14//!
15//! // 1. Define your Payload (Must be Serialize/Deserialize)
16//! #[derive(Debug, Serialize, Deserialize)]
17//! struct Message {
18//!     from: String,
19//!     to: String,
20//!     content: String,
21//! }
22//!
23//! // 2. Define your Job Struct (Can hold internal state, database pools, etc.)
24//! struct MailSender {
25//!     prefix: String,
26//! }
27//!
28//! // 3. Implement the Job Trait
29//! #[async_trait]
30//! impl Job for MailSender {
31//!     const NAME: &'static str = "send_email";
32//!     type Payload = Message;
33//!
34//!     async fn run(&self, payload: Self::Payload) {
35//!         // You can access internal state (self.prefix) and the payload
36//!         println!("{}: Sending email from {} to {}",
37//!             self.prefix, payload.from, payload.to
38//!         );
39//!     }
40//! }
41//!
42//! #[tokio::main]
43//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
44//! #     // Hidden setup code to make the doc cleaner
45//! #     let conn_str = std::env::var("DATABASE_URL").unwrap_or("postgres://postgres:postgres@localhost:5432".to_string());
46//! #     let pool = sqlx::postgres::PgPoolOptions::new()
47//! #         .connect(&conn_str).await?;
48//! #
49//!     // 4. Initialize Agenda
50//!     let mut agenda = Agenda::new(pool, None).await?;
51//!
52//!     // 5. Register the Job Handler
53//!     // We pass an instance of MailSender, allowing us to inject state (e.g., "Mailer v1")
54//!     let mailer = MailSender { prefix: "Mailer v1".to_string() };
55//!     agenda.register(mailer).await;
56//!
57//!     // 6. Schedule a Job
58//!     let message = Message {
59//!         from: "alice@example.com".into(),
60//!         to: "bob@example.com".into(),
61//!         content: "Hello World".into(),
62//!     };
63//!
64//!     // Run every minute ("0 * * * * *")
65//!     let schedule = Schedule::from_str("0 * * * * *").unwrap();
66//!     
67//!     agenda.schedule::<MailSender>(schedule, message).await?;
68//!
69//!     // 7. Start the Agenda Runner (blocking)
70//!     // In a real app, you might want to spawn this: tokio::spawn(agenda.start());
71//!     // agenda.start().await;
72//!    Ok(())
73//! }
74//! ```
75
76mod agenda;
77mod error;
78mod job;
79
80pub mod prelude {
81    pub use crate::Agenda;
82    pub use crate::AgendaError;
83    pub use crate::Job;
84    pub use async_trait::async_trait;
85    pub use cron::Schedule;
86    pub use serde::{Deserialize, Serialize};
87}
88
89pub use sqlx;
90
91pub use agenda::Agenda;
92pub use error::AgendaError;
93pub use job::Job;