fluxion_stream/types.rs
1// Copyright 2025 Umberto Gotti <umberto.gotti@umbertogotti.dev>
2// Licensed under the Apache License, Version 2.0
3// http://www.apache.org/licenses/LICENSE-2.0
4
5//! Common types and type aliases used throughout the fluxion-stream crate.
6//!
7//! This module centralizes shared types to reduce duplication and improve maintainability.
8
9use fluxion_core::Ordered;
10use std::fmt::Debug;
11
12/// Represents a value paired with its previous value in the stream.
13///
14/// Used by [`CombineWithPreviousExt`](crate::CombineWithPreviousExt) to provide
15/// both current and previous values.
16#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
17pub struct WithPrevious<T> {
18 /// The previous value in the stream, if any
19 pub previous: Option<T>,
20 /// The current value in the stream
21 pub current: T,
22}
23
24impl<T> WithPrevious<T> {
25 /// Creates a new WithPrevious with the given previous and current values.
26 pub fn new(previous: Option<T>, current: T) -> Self {
27 Self { previous, current }
28 }
29
30 /// Returns true if there is a previous value.
31 pub fn has_previous(&self) -> bool {
32 self.previous.is_some()
33 }
34
35 /// Returns a tuple of references to (previous, current) if previous exists.
36 pub fn as_pair(&self) -> Option<(&T, &T)> {
37 self.previous.as_ref().map(|prev| (prev, &self.current))
38 }
39}
40
41impl<T: Ordered> Ordered for WithPrevious<T> {
42 type Inner = T::Inner;
43
44 fn order(&self) -> u64 {
45 self.current.order()
46 }
47
48 fn get(&self) -> &Self::Inner {
49 self.current.get()
50 }
51
52 fn with_order(value: Self::Inner, order: u64) -> Self {
53 Self {
54 previous: None,
55 current: T::with_order(value, order),
56 }
57 }
58
59 fn into_inner(self) -> Self::Inner {
60 self.current.into_inner()
61 }
62}
63
64/// State container holding the latest values from multiple combined streams.
65///
66/// Used by operators that combine multiple streams such as [`combine_latest`](crate::CombineLatestExt::combine_latest),
67/// [`with_latest_from`](crate::WithLatestFromExt::with_latest_from), and
68/// [`emit_when`](crate::EmitWhenExt::emit_when).
69///
70/// # Examples
71///
72/// ```
73/// use fluxion_stream::CombinedState;
74///
75/// let state = CombinedState::new(vec![1, 2, 3]);
76/// assert_eq!(state.values().len(), 3);
77/// assert_eq!(state.values()[0], 1);
78/// ```
79#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
80pub struct CombinedState<V>
81where
82 V: Clone + Debug + Ord,
83{
84 state: Vec<V>,
85}
86
87impl<V> CombinedState<V>
88where
89 V: Clone + Debug + Ord,
90{
91 /// Creates a new CombinedState with the given vector of values.
92 pub fn new(state: Vec<V>) -> Self {
93 Self { state }
94 }
95
96 /// Returns a reference to the internal values vector.
97 pub fn values(&self) -> &Vec<V> {
98 &self.state
99 }
100
101 /// Returns the number of streams in the combined state.
102 pub fn len(&self) -> usize {
103 self.state.len()
104 }
105
106 /// Returns true if there are no streams in the combined state.
107 pub fn is_empty(&self) -> bool {
108 self.state.is_empty()
109 }
110}
111
112impl<V> Ordered for CombinedState<V>
113where
114 V: Clone + Debug + Ord,
115{
116 type Inner = Self;
117
118 fn order(&self) -> u64 {
119 // CombinedState doesn't have its own order - it's always wrapped by an Ordered type
120 // This should never be called directly
121 0
122 }
123
124 fn get(&self) -> &Self::Inner {
125 self
126 }
127
128 fn with_order(value: Self::Inner, _order: u64) -> Self {
129 value
130 }
131
132 fn into_inner(self) -> Self::Inner {
133 self
134 }
135}
136
137/// Type alias for the common trait bounds used for ordered stream items.
138///
139/// This trait requires that types are:
140/// - `Ordered`: Have temporal ordering
141/// - `Clone`: Can be duplicated
142/// - `Debug`: Can be formatted for debugging
143/// - `Ord`: Have total ordering
144/// - `Send + Sync`: Can be safely transferred between threads
145/// - `Unpin`: Can be moved after being pinned
146/// - `'static`: Contains no non-static references
147///
148/// # Usage
149///
150/// Instead of writing:
151/// ```
152/// # use fluxion_stream::OrderedStreamItem;
153/// # use fluxion_core::Ordered;
154/// # use std::fmt::Debug;
155/// fn process_stream<T>()
156/// where
157/// T: Ordered + Clone + Debug + Ord + Send + Sync + Unpin + 'static
158/// # {}
159/// ```
160///
161/// You can write:
162/// ```
163/// # use fluxion_stream::OrderedStreamItem;
164/// fn process_stream<T>()
165/// where
166/// T: OrderedStreamItem
167/// # {}
168/// ```
169pub trait OrderedStreamItem: Ordered + Clone + Debug + Ord + Send + Sync + Unpin + 'static {}
170
171// Blanket implementation for all types that satisfy the bounds
172impl<T> OrderedStreamItem for T where
173 T: Ordered + Clone + Debug + Ord + Send + Sync + Unpin + 'static
174{
175}
176
177/// Type alias for the common trait bounds used for the inner values of ordered stream items.
178///
179/// This trait requires that inner types are:
180/// - `Clone`: Can be duplicated
181/// - `Debug`: Can be formatted for debugging
182/// - `Ord`: Have total ordering
183/// - `Send + Sync`: Can be safely transferred between threads
184/// - `'static`: Contains no non-static references
185///
186/// # Usage
187///
188/// Instead of writing:
189/// ```
190/// # use std::fmt::Debug;
191/// fn process_inner<T>()
192/// where
193/// T: Clone + Debug + Ord + Send + Sync + 'static
194/// # {}
195/// ```
196///
197/// You can write:
198/// ```
199/// # use fluxion_stream::OrderedInner;
200/// fn process_inner<T>()
201/// where
202/// T: OrderedInner
203/// # {}
204/// ```
205pub trait OrderedInner: Clone + Debug + Ord + Send + Sync + 'static {}
206
207// Blanket implementation for all types that satisfy the bounds
208impl<T> OrderedInner for T where T: Clone + Debug + Ord + Send + Sync + 'static {}
209
210/// Type alias for the common trait bounds used for ordered items that need to be
211/// unwrapped (without Unpin requirement).
212///
213/// Used in scenarios where the inner value needs to implement Ordered but doesn't
214/// need to be Unpin.
215pub trait OrderedInnerUnwrapped: Clone + Debug + Ord + Send + Sync + Unpin + 'static {}
216
217// Blanket implementation
218impl<T> OrderedInnerUnwrapped for T where T: Clone + Debug + Ord + Send + Sync + Unpin + 'static {}