zrx_stream/stream/combinator/tuple.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//! Stream tuple.
27
28use crate::stream::workspace::Workflow;
29use crate::stream::Stream;
30
31pub mod cons;
32mod convert;
33mod ext;
34pub mod join;
35
36pub use cons::StreamTupleCons;
37pub use convert::IntoStreamTuple;
38pub use ext::StreamTupleExt;
39pub use join::StreamTupleJoin;
40
41// ----------------------------------------------------------------------------
42// Traits
43// ----------------------------------------------------------------------------
44
45/// Stream tuple.
46///
47/// Stream tuples are heterogeneous collections of streams, which are essential
48/// to differentially source inputs for functions that take multiple arguments.
49/// They are implemented as tuples of streams with the help of macros in sizes
50/// of 1 to 8, which also applies to all derived traits.
51///
52/// Operators implemented with stream tuples include:
53///
54/// - [`Stream::join`] + variations
55/// - [`Stream::left_join`] + variations
56/// - [`Stream::full_join`] + variations
57///
58/// As such, [`StreamTuple`] is solely a base trait with some methods attached
59/// that allows to conveniently work with stream tuples. Trait derivations like
60/// [`StreamTupleJoin`] and friends extend the functionality of [`StreamTuple`]
61/// to implement join operations on tuples of streams and more.
62pub trait StreamTuple<I>: Sized {
63 fn workflow(&self) -> &Workflow<I>;
64 fn ids(&self) -> Vec<usize>;
65}
66
67// ----------------------------------------------------------------------------
68// Macros
69// ----------------------------------------------------------------------------
70
71/// Implements stream tuple trait with all items required.
72macro_rules! impl_stream_tuple {
73 ($($T:ident),+ $(,)?) => {
74 impl<I, $($T),+> StreamTuple<I>
75 for ($(Stream<I, $T>,)+)
76 {
77 #[inline]
78 fn workflow(&self) -> &Workflow<I> {
79 &self.0.workflow
80 }
81
82 #[inline]
83 fn ids(&self) -> Vec<usize> {
84 #[allow(non_snake_case)]
85 let ($($T,)+) = self;
86 vec![$($T.id),+]
87 }
88 }
89 };
90}
91
92// ----------------------------------------------------------------------------
93
94impl_stream_tuple!(T1);
95impl_stream_tuple!(T1, T2);
96impl_stream_tuple!(T1, T2, T3);
97impl_stream_tuple!(T1, T2, T3, T4);
98impl_stream_tuple!(T1, T2, T3, T4, T5);
99impl_stream_tuple!(T1, T2, T3, T4, T5, T6);
100impl_stream_tuple!(T1, T2, T3, T4, T5, T6, T7);
101impl_stream_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);