use std::fmt::Display;
use zrx_scheduler::step::error::IntoResult;
use zrx_scheduler::step::{Result, Scope};
use zrx_scheduler::Key;
use crate::stream::function::arguments::{ForId, ForKey, ForScope, ForValue};
use crate::stream::function::catch;
pub trait DefaultFn<A, I, T>: Send + 'static {
fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>>;
}
impl<F, R, I, T> DefaultFn<ForScope, I, T> for F
where
F: Fn(&mut Scope<I>) -> R + Send + 'static,
R: IntoResult<Option<T>>,
I: Display,
{
#[cfg_attr(
feature = "tracing",
tracing::instrument(
level = "debug", skip_all, fields(key = %scope.key())
)
)]
#[inline]
fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
catch(|| self(scope).into_result())
}
}
impl<F, R, I, T> DefaultFn<ForKey, I, T> for F
where
F: Fn(&Key<I>) -> R + Send + 'static,
R: IntoResult<Option<T>>,
I: Display,
{
#[cfg_attr(
feature = "tracing",
tracing::instrument(
level = "debug", skip_all, fields(key = %scope.key())
)
)]
#[inline]
fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
catch(|| self(scope.key()).into_result())
}
}
impl<F, R, I, T> DefaultFn<ForId, I, T> for F
where
F: Fn(&I) -> R + Send + 'static,
R: IntoResult<Option<T>>,
I: Display,
{
#[cfg_attr(
feature = "tracing",
tracing::instrument(
level = "debug", skip_all, fields(key = %scope.key())
)
)]
#[inline]
fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
catch(|| self(scope.key().try_as_id()?).into_result())
}
}
impl<F, R, I, T> DefaultFn<ForValue, I, T> for F
where
F: Fn() -> R + Send + 'static,
R: IntoResult<Option<T>>,
I: Display,
{
#[cfg_attr(
feature = "tracing",
tracing::instrument(
level = "debug", skip_all, fields(key = %scope.key())
)
)]
#[inline]
fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
catch(|| self().into_result())
}
}