//! StatusReporter actor: fire-and-forget Forgejo commit status updates. //! //! Receives status update messages and POSTs them to the Forgejo API. use swactor::actor::{ActorInterface, Ctx}; use crate::StatusUpdate; /// Messages the StatusReporter can receive. #[derive(Debug, Clone)] pub enum StatusReporterMsg { Report { update: StatusUpdate, forgejo_url: String, forgejo_token: String, }, } /// StatusReporter actor state. pub struct StatusReporter; impl StatusReporter { pub fn new() -> Self { Self } #[cfg(feature = "local")] fn post_status(update: &StatusUpdate, forgejo_url: &str, forgejo_token: &str) { let url = format!( "{}/api/v1/repos/{}/{}/statuses/{}", forgejo_url.trim_end_matches('/'), update.repo_owner, update.repo_name, update.commit_sha, ); let body = serde_json::json!({ "state": update.state, "context": update.context, "description": update.description, }); let result = ureq::post(&url) .set("Authorization", &format!("token {forgejo_token}")) .set("Content-Type", "application/json") .send_string(&body.to_string()); if let Err(e) = result { eprintln!("StatusReporter: failed to post status to {url}: {e}"); } } } impl ActorInterface for StatusReporter { type Incoming = StatusReporterMsg; type Response = (); fn handle(&mut self, _ctx: &Ctx, msg: StatusReporterMsg) { match msg { StatusReporterMsg::Report { update, forgejo_url, forgejo_token, } => { #[cfg(feature = "local")] Self::post_status(&update, &forgejo_url, &forgejo_token); #[cfg(not(feature = "local"))] { let _ = (update, forgejo_url, forgejo_token); } } } } }