1use std::collections::HashMap;
2use std::sync::Arc;
3use yq::{decode_job, Job, JobType, YqError, YqResult, YqRunJobError};
4
5pub trait SyncJob: Job {
6 fn execute(self, mid: i64, state: Self::State) -> Result<(), String>;
7}
8
9type SyncJobFn<S> = Arc<dyn Fn(i64, String, S) -> Result<(), String>>;
10
11pub(crate) struct SyncJobFns<S>(HashMap<JobType, SyncJobFn<S>>);
12
13impl<S> SyncJobFns<S> {
14 pub(crate) fn new() -> SyncJobFns<S> {
15 SyncJobFns::<S>(HashMap::default())
16 }
17
18 pub(crate) fn reg_job(&mut self, job_type: JobType, job_fn: SyncJobFn<S>) -> YqResult<()> {
19 if self.0.insert(job_type.clone(), job_fn).is_some() {
20 Err(YqError::DupJobType(job_type))
21 } else {
22 Ok(())
23 }
24 }
25
26 pub(crate) fn handle(&self, mid: i64, mcontent: String, state: S) -> YqResult<()> {
27 let (job_type, job_data) = decode_job(&mcontent)?;
28
29 let job_fn = match self.0.get(job_type) {
30 Some(job_fn) => job_fn,
31 None => {
32 return Err(YqError::JobTypeMissing(JobType::from(job_type.to_string())));
33 }
34 };
35
36 job_fn(mid, job_data.to_string(), state)
37 .map_err(|error| YqError::RunJobError(YqRunJobError::new(job_data.to_string(), error)))
38 }
39}