Skip to main content

sofie_db/
call.rs

1use std::sync::Arc;
2
3use sofie_core::Result;
4
5use crate::{BoxFuture, Outcome, Reply, Resolve};
6
7pub trait Call<C, Args>: Clone + Send + Sync + 'static {
8    type Outcome: Outcome + 'static;
9
10    fn call(&self, context: &mut C) -> impl Future<Output = Result<Self::Outcome>> + Send;
11}
12
13macro_rules! call {
14    ($($argument:ident),*) => {
15        impl<C, F, Fut, O, $($argument,)*> Call<C, ($($argument,)*)> for F
16        where
17            C: Send,
18            F: Fn($($argument),*) -> Fut + Clone + Send + Sync + 'static,
19            Fut: Future<Output = Result<O>> + Send,
20            O: Outcome + 'static,
21            $($argument: Resolve<C> + Send,)*
22        {
23            type Outcome = O;
24
25            #[allow(non_snake_case, unused_variables, reason = "arguments are named after their types")]
26            fn call(&self, context: &mut C) -> impl Future<Output = Result<O>> + Send {
27                async move {
28                    $(let $argument = $argument::resolve(context).await?;)*
29                    self($($argument),*).await
30                }
31            }
32        }
33    };
34}
35
36macro_rules! calls {
37    () => {
38        call!();
39    };
40    ($first:ident $(, $rest:ident)*) => {
41        call!($first $(, $rest)*);
42        calls!($($rest),*);
43    };
44}
45
46calls!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
47
48pub trait AnyOutcome: Outcome {
49    fn into_reply(self: Box<Self>) -> Result<Reply>;
50}
51
52impl<O: Outcome> AnyOutcome for O {
53    fn into_reply(self: Box<Self>) -> Result<Reply> {
54        (*self).reply()
55    }
56}
57
58pub type Run<C> =
59    Arc<dyn for<'c> Fn(&'c mut C) -> BoxFuture<'c, Result<Box<dyn AnyOutcome>>> + Send + Sync>;
60
61pub fn erase<C: Send + 'static, Args, F: Call<C, Args>>(function: F) -> Run<C> {
62    Arc::new(move |context| {
63        let function = function.clone();
64        Box::pin(async move {
65            let outcome = function.call(context).await?;
66            Ok(Box::new(outcome) as Box<dyn AnyOutcome>)
67        })
68    })
69}
70
71#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72pub enum Trigger {
73    /// A message naming it: a queued job, or each record's job of a schedule.
74    Queued,
75    On(&'static str),
76    Every(crate::worker::Cadence),
77}
78
79pub struct Entry<C> {
80    pub name: &'static str,
81    pub trigger: Trigger,
82    pub run: Run<C>,
83}