Skip to main content

zrx_stream/stream/combinator/tuple/
convert.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 conversions.
27
28use crate::stream::Stream;
29
30use super::StreamTuple;
31
32// ----------------------------------------------------------------------------
33// Traits
34// ----------------------------------------------------------------------------
35
36/// Conversion into [`StreamTuple`].
37pub trait IntoStreamTuple<I> {
38    /// Output type of conversion.
39    type Output: StreamTuple<I>;
40
41    /// Converts a tuple of stream references into a stream tuple.
42    ///
43    /// # Examples
44    ///
45    /// ```
46    /// use zrx_stream::combinator::IntoStreamTuple;
47    /// use zrx_stream::workspace::Workspace;
48    ///
49    /// // Create workspace and workflow
50    /// let workspace = Workspace::<&str>::new();
51    /// let workflow = workspace.add_workflow();
52    ///
53    /// // Create streams (heterogeneous)
54    /// let a = workflow.add_source::<i32>();
55    /// let b = workflow.add_source::<bool>();
56    ///
57    /// // Create stream tuple
58    /// let tuple = (&a, &b).into_stream_tuple();
59    /// ```
60    fn into_stream_tuple(self) -> Self::Output;
61}
62
63// ----------------------------------------------------------------------------
64// Trait implementations
65// ----------------------------------------------------------------------------
66
67impl<I, T> IntoStreamTuple<I> for &Stream<I, T> {
68    type Output = (Stream<I, T>,);
69
70    /// Converts a stream reference into a stream tuple.
71    ///
72    /// Albeit this conversion is trivial, it allows to pass stream references
73    /// to functions that expect tuples, which can be quite convenient.
74    ///
75    /// # Examples
76    ///
77    /// ```
78    /// use zrx_stream::combinator::IntoStreamTuple;
79    /// use zrx_stream::workspace::Workspace;
80    ///
81    /// // Create workspace and workflow
82    /// let workspace = Workspace::<&str>::new();
83    /// let workflow = workspace.add_workflow();
84    ///
85    /// // Create stream
86    /// let stream = workflow.add_source::<i32>();
87    ///
88    /// // Create stream tuple
89    /// let tuple = stream.into_stream_tuple();
90    /// ```
91    #[inline]
92    fn into_stream_tuple(self) -> Self::Output {
93        (self.clone(),)
94    }
95}
96
97// ----------------------------------------------------------------------------
98// Macros
99// ----------------------------------------------------------------------------
100
101/// Implements stream tuple conversion trait.
102macro_rules! impl_into_stream_tuple {
103    ($($T:ident),+ $(,)?) => {
104        impl<I, $($T),+> IntoStreamTuple<I> for ($(&Stream<I, $T>,)+) {
105            type Output = ($(Stream<I, $T>,)+);
106
107            #[inline]
108            fn into_stream_tuple(self) -> Self::Output {
109                #[allow(non_snake_case)]
110                let ($($T,)+) = self;
111                ($($T.clone(),)+)
112            }
113        }
114    };
115}
116
117// ----------------------------------------------------------------------------
118
119impl_into_stream_tuple!(T1);
120impl_into_stream_tuple!(T1, T2);
121impl_into_stream_tuple!(T1, T2, T3);
122impl_into_stream_tuple!(T1, T2, T3, T4);
123impl_into_stream_tuple!(T1, T2, T3, T4, T5);
124impl_into_stream_tuple!(T1, T2, T3, T4, T5, T6);
125impl_into_stream_tuple!(T1, T2, T3, T4, T5, T6, T7);
126impl_into_stream_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);