Skip to main content

zrx_stream/stream/function/signature/
default.rs

1// Copyright (c) 2025-2026 Zensical and contributors
2
3// SPDX-License-Identifier: MIT
4// All contributions are certified under the DCO
5
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to
8// deal in the Software without restriction, including without limitation the
9// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10// sell copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12
13// The above copyright notice and this permission notice shall be included in
14// all copies or substantial portions of the Software.
15
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22// IN THE SOFTWARE.
23
24// ----------------------------------------------------------------------------
25
26//! Default function.
27
28use std::fmt::Display;
29
30use zrx_scheduler::step::error::IntoResult;
31use zrx_scheduler::step::{Result, Scope};
32use zrx_scheduler::Key;
33
34use crate::stream::function::arguments::{ForId, ForKey, ForScope, ForValue};
35use crate::stream::function::catch;
36
37// ----------------------------------------------------------------------------
38// Traits
39// ----------------------------------------------------------------------------
40
41/// Default function.
42pub trait DefaultFn<A, I, T>: Send + 'static {
43    /// Executes the default function.
44    ///
45    /// # Errors
46    ///
47    /// This method returns an error if the function fails to execute.
48    fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>>;
49}
50
51// ----------------------------------------------------------------------------
52// Blanket implementations
53// ----------------------------------------------------------------------------
54
55impl<F, R, I, T> DefaultFn<ForScope, I, T> for F
56where
57    F: Fn(&mut Scope<I>) -> R + Send + 'static,
58    R: IntoResult<Option<T>>,
59    I: Display,
60{
61    #[cfg_attr(
62        feature = "tracing",
63        tracing::instrument(
64            level = "debug", skip_all, fields(key = %scope.key())
65        )
66    )]
67    #[inline]
68    fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
69        catch(|| self(scope).into_result())
70    }
71}
72
73// ----------------------------------------------------------------------------
74
75impl<F, R, I, T> DefaultFn<ForKey, I, T> for F
76where
77    F: Fn(&Key<I>) -> R + Send + 'static,
78    R: IntoResult<Option<T>>,
79    I: Display,
80{
81    #[cfg_attr(
82        feature = "tracing",
83        tracing::instrument(
84            level = "debug", skip_all, fields(key = %scope.key())
85        )
86    )]
87    #[inline]
88    fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
89        catch(|| self(scope.key()).into_result())
90    }
91}
92
93// ----------------------------------------------------------------------------
94
95impl<F, R, I, T> DefaultFn<ForId, I, T> for F
96where
97    F: Fn(&I) -> R + Send + 'static,
98    R: IntoResult<Option<T>>,
99    I: Display,
100{
101    #[cfg_attr(
102        feature = "tracing",
103        tracing::instrument(
104            level = "debug", skip_all, fields(key = %scope.key())
105        )
106    )]
107    #[inline]
108    fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
109        catch(|| self(scope.key().try_as_id()?).into_result())
110    }
111}
112
113// ----------------------------------------------------------------------------
114
115impl<F, R, I, T> DefaultFn<ForValue, I, T> for F
116where
117    F: Fn() -> R + Send + 'static,
118    R: IntoResult<Option<T>>,
119    I: Display,
120{
121    #[cfg_attr(
122        feature = "tracing",
123        tracing::instrument(
124            level = "debug", skip_all, fields(key = %scope.key())
125        )
126    )]
127    #[inline]
128    fn execute(&self, scope: &mut Scope<I>) -> Result<Option<T>> {
129        catch(|| self().into_result())
130    }
131}