zrx_stream/stream/function/adapter/splat.rs
1// Copyright (c) 2025 Zensical and contributors
2
3// SPDX-License-Identifier: MIT
4// Third-party contributions licensed under 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//! Function adapter to splat the function's arguments.
27
28use std::ops::Deref;
29
30// ----------------------------------------------------------------------------
31// Structs
32// ----------------------------------------------------------------------------
33
34/// Function adapter to splat the function's arguments.
35///
36/// This adapter is just a wrapper around a function and acts as a marker to
37/// omit conflicting implementations of function traits with more specialized
38/// implementations. This implementation passes the arguments as a [`Splat`][]
39/// to the function, allowing to conveniently work with multiple arguments.
40///
41/// Use the [`with_splat`] function to wrap a function with this adapter, since
42/// this type is not part of the streaming API, as it's only necessary for the
43/// implementation of the function traits themselves. See the documentation of
44/// [`with_splat`] for more information.
45///
46/// [`Splat`]: crate::stream::function::Splat
47#[derive(Clone, Debug)]
48#[repr(transparent)]
49pub struct WithSplat<F> {
50 /// Function.
51 function: F,
52}
53
54// ----------------------------------------------------------------------------
55// Trait implementations
56// ----------------------------------------------------------------------------
57
58impl<F> Deref for WithSplat<F> {
59 type Target = F;
60
61 /// Dereferences to the wrapped function.
62 #[inline]
63 fn deref(&self) -> &Self::Target {
64 &self.function
65 }
66}
67
68// ----------------------------------------------------------------------------
69// Functions
70// ----------------------------------------------------------------------------
71
72/// Splats the function's arguments.
73///
74/// Function traits that implement this trait allow to pass a function that
75/// receives a splat argument instead of a single tuple argument.
76///
77/// Note that there are no trait bounds, since [`WithSplat`] is merely a marker
78/// struct that is used to differentiate between function implementations. This
79/// is also why the returned type implements [`Deref`], so that it behaves like
80/// the underlying function.
81///
82/// # Examples
83///
84/// ```
85/// # use std::error::Error;
86/// # fn main() -> Result<(), Box<dyn Error>> {
87/// use zrx_stream::function::{with_splat, InspectFn};
88///
89/// // Define and execute function
90/// let f = |&a: &i32, &b: &i32| println!("({a}, {b})");
91/// with_splat(f).execute(&"id", &(1, 2))?;
92/// # Ok(())
93/// # }
94/// ```
95#[inline]
96pub fn with_splat<F>(f: F) -> WithSplat<F> {
97 WithSplat { function: f }
98}