Skip to main content

hydro_lang/live_collections/
boundedness.rs

1//! Type declarations for boundedness markers, which indicate whether a live collection is finite
2//! and immutable ([`Bounded`]) or asynchronously arriving over time ([`Unbounded`]).
3
4use sealed::sealed;
5
6use super::keyed_singleton::{BoundedValue, KeyedSingletonBound};
7use crate::compile::ir::BoundKind;
8
9/// A marker trait indicating whether a stream’s length is bounded (finite) or unbounded (potentially infinite).
10///
11/// Implementors of this trait use it to signal the boundedness property of a stream.
12#[sealed]
13pub trait Boundedness: KeyedBoundFoldLike {
14    /// `true` if the bound is [`Bounded`], `false` if it is [`Unbounded`].
15    const BOUNDED: bool;
16
17    /// The [`BoundKind`] corresponding to this type.
18    const BOUND_KIND: BoundKind = if Self::BOUNDED {
19        BoundKind::Bounded
20    } else {
21        BoundKind::Unbounded
22    };
23}
24
25/// Marks the stream as being unbounded, which means that it is not
26/// guaranteed to be complete in finite time.
27pub enum Unbounded {}
28
29#[sealed]
30impl Boundedness for Unbounded {
31    const BOUNDED: bool = false;
32}
33
34/// Marks the stream as being bounded, which means that it is guaranteed
35/// to be complete in finite time.
36pub enum Bounded {}
37
38#[sealed]
39impl Boundedness for Bounded {
40    const BOUNDED: bool = true;
41}
42
43#[sealed]
44#[diagnostic::on_unimplemented(
45    message = "The input collection must be bounded (`Bounded`), but has bound `{Self}`. Strengthen the boundedness upstream or consider a different API.",
46    label = "required here",
47    note = "To intentionally process a non-deterministic snapshot or batch, you may want to use a `sliced!` region. This introduces non-determinism so avoid unless necessary."
48)]
49/// Marker trait that is implemented for the [`Bounded`] boundedness guarantee.
50pub trait IsBounded: Boundedness {}
51
52#[sealed]
53#[diagnostic::do_not_recommend]
54impl IsBounded for Bounded {}
55
56/// Helper trait that determines the boundedness for the result of keyed aggregations.
57#[sealed]
58pub trait KeyedBoundFoldLike {
59    /// The boundedness of the keyed singleton if the values for each key will asynchronously change.
60    type WhenValueUnbounded: KeyedSingletonBound<UnderlyingBound = Self>;
61    /// The boundedness of the keyed singleton if the value for each key is immutable.
62    type WhenValueBounded: KeyedSingletonBound<UnderlyingBound = Self>;
63}
64
65#[sealed]
66impl KeyedBoundFoldLike for Unbounded {
67    type WhenValueUnbounded = Unbounded;
68    type WhenValueBounded = BoundedValue;
69}
70
71#[sealed]
72impl KeyedBoundFoldLike for Bounded {
73    type WhenValueUnbounded = Bounded;
74    type WhenValueBounded = Bounded;
75}