Skip to main content

zrx_stream/stream/value/
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//! Tuple.
27
28use zrx_scheduler::value::{IntoOwned, TryFromValues, Value};
29
30// ----------------------------------------------------------------------------
31// Traits
32// ----------------------------------------------------------------------------
33
34/// Presence.
35pub trait Presence: 'static {}
36
37// ----------------------------------------------------------------------------
38
39/// Tuple.
40///
41/// This trait is used to define different configurations of tuples for join
42/// operators, which centers around the presence of values in the tuple. Note
43/// that the argument type defines the expected values in the tuple, and is
44/// used as the join operator's own argument type.
45///
46/// In order to isolate lifetimes in the trait, and to omit the need for using
47/// higher-ranked trait bounds in each operator, the implementations account
48/// for the lifetimes with said higher-ranked trait bounds. While they are
49/// rather ugly, there's no other way to express it without them.
50///
51/// This trait doesn't have a bound on [`Presence`], so we can keep operator
52/// implementations simpler, but it's enforced on wrappers that use it.
53pub trait Tuple<P>: Value {
54    /// Tuple arguments type.
55    type Arguments<'a>: TryFromValues<'a> + IntoOwned<Owned = Self>;
56}
57
58// ----------------------------------------------------------------------------
59// Structs
60// ----------------------------------------------------------------------------
61
62/// All items are required.
63pub struct All;
64
65/// First item is required.
66pub struct First;
67
68/// All items are optional.
69pub struct Any;
70
71// ----------------------------------------------------------------------------
72// Implementations
73// ----------------------------------------------------------------------------
74
75impl Presence for All {}
76
77impl Presence for First {}
78
79impl Presence for Any {}
80
81// ----------------------------------------------------------------------------
82// Macros
83// ----------------------------------------------------------------------------
84
85/// Implements tuple trait with all items required.
86macro_rules! impl_tuple_all {
87    ($($T:ident),+ $(,)?) => {
88        impl<$($T),+> Tuple<All> for ($($T,)+)
89        where
90            Self: Value,
91            for<'a> ($(&'a $T,)+):
92                TryFromValues<'a> + IntoOwned<Owned = Self>,
93        {
94            type Arguments<'a> = ($(&'a $T,)*);
95        }
96    };
97}
98
99/// Implements tuple trait with first item required.
100macro_rules! impl_tuple_first {
101    ($T1:ident $(, $T:ident)* $(,)?) => {
102        impl<$T1 $(, $T)*> Tuple<First> for ($T1, $(Option<$T>),*)
103        where
104            Self: Value,
105            for<'a> (&'a $T1, $(Option<&'a $T>),*):
106                TryFromValues<'a> + IntoOwned<Owned = Self>,
107        {
108            type Arguments<'a> = (&'a $T1, $(Option<&'a $T>),*);
109        }
110    };
111}
112
113/// Implements tuple trait with all items optional.
114macro_rules! impl_tuple_any {
115    ($($T:ident),+ $(,)?) => {
116        impl<$($T),+> Tuple<Any> for ($(Option<$T>,)+)
117        where
118            Self: Value,
119            for<'a> ($(Option<&'a $T>,)+):
120                TryFromValues<'a> + IntoOwned<Owned = Self>,
121        {
122            type Arguments<'a> = ($(Option<&'a $T>,)*);
123        }
124    };
125}
126
127/// Implements tuple traits.
128macro_rules! impl_tuple {
129    ($($T:ident),+ $(,)?) => {
130        impl_tuple_all!($($T),+);
131        impl_tuple_first!($($T),+);
132        impl_tuple_any!($($T),+);
133    };
134}
135
136// ----------------------------------------------------------------------------
137
138impl_tuple!(T1);
139impl_tuple!(T1, T2);
140impl_tuple!(T1, T2, T3);
141impl_tuple!(T1, T2, T3, T4);
142impl_tuple!(T1, T2, T3, T4, T5);
143impl_tuple!(T1, T2, T3, T4, T5, T6);
144impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
145impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);