hydro_lang/
forward_handle.rs1use sealed::sealed;
4
5use crate::compile::builder::CycleId;
6use crate::location::Location;
7use crate::location::dynamic::LocationId;
8use crate::staging_util::Invariant;
9
10#[sealed]
11pub(crate) trait ReceiverKind {}
12
13pub enum ForwardRef {}
18
19#[sealed]
20impl ReceiverKind for ForwardRef {}
21
22pub enum TickCycle {}
27
28#[sealed]
29impl ReceiverKind for TickCycle {}
30
31pub(crate) trait ReceiverComplete<'a, Marker>
32where
33 Marker: ReceiverKind,
34{
35 fn complete(self, cycle_id: CycleId, expected_location: LocationId);
36}
37
38pub(crate) trait CycleCollection<'a, Kind>: ReceiverComplete<'a, Kind>
39where
40 Kind: ReceiverKind,
41{
42 type Location: Location<'a>;
43
44 fn create_source(id: CycleId, location: Self::Location) -> Self;
45}
46
47pub(crate) trait CycleCollectionWithInitial<'a, Kind>: ReceiverComplete<'a, Kind>
48where
49 Kind: ReceiverKind,
50{
51 type Location: Location<'a>;
52
53 fn location(&self) -> &Self::Location;
54
55 fn create_source_with_initial(
56 cycle_id: CycleId,
57 initial: Self,
58 location: Self::Location,
59 ) -> Self;
60}
61
62#[expect(
66 private_bounds,
67 reason = "only Hydro collections can implement ReceiverComplete"
68)]
69pub struct ForwardHandle<'a, C: ReceiverComplete<'a, ForwardRef>> {
70 completed: bool,
71 cycle_id: CycleId,
72 expected_location: LocationId,
73 _phantom: Invariant<'a, C>,
74}
75
76#[expect(
77 private_bounds,
78 reason = "only Hydro collections can implement ReceiverComplete"
79)]
80impl<'a, C: ReceiverComplete<'a, ForwardRef>> ForwardHandle<'a, C> {
81 pub(crate) fn new(cycle_id: CycleId, expected_location: LocationId) -> Self {
82 Self {
83 completed: false,
84 cycle_id,
85 expected_location,
86 _phantom: std::marker::PhantomData,
87 }
88 }
89}
90
91impl<'a, C: ReceiverComplete<'a, ForwardRef>> Drop for ForwardHandle<'a, C> {
92 fn drop(&mut self) {
93 assert!(
94 self.completed || std::thread::panicking(),
95 "ForwardHandle dropped without being completed"
96 );
97 }
98}
99
100#[expect(
101 private_bounds,
102 reason = "only Hydro collections can implement ReceiverComplete"
103)]
104impl<'a, C: ReceiverComplete<'a, ForwardRef>> ForwardHandle<'a, C> {
105 pub fn complete(mut self, stream: impl Into<C>) {
112 self.completed = true;
113 C::complete(stream.into(), self.cycle_id, self.expected_location.clone())
114 }
115}
116
117#[expect(
121 private_bounds,
122 reason = "only Hydro collections can implement ReceiverComplete"
123)]
124pub struct TickCycleHandle<'a, C: ReceiverComplete<'a, TickCycle>> {
125 completed: bool,
126 cycle_id: CycleId,
127 expected_location: LocationId,
128 _phantom: Invariant<'a, C>,
129}
130
131#[expect(
132 private_bounds,
133 reason = "only Hydro collections can implement ReceiverComplete"
134)]
135impl<'a, C: ReceiverComplete<'a, TickCycle>> TickCycleHandle<'a, C> {
136 pub(crate) fn new(cycle_id: CycleId, expected_location: LocationId) -> Self {
137 Self {
138 completed: false,
139 cycle_id,
140 expected_location,
141 _phantom: std::marker::PhantomData,
142 }
143 }
144}
145
146impl<'a, C: ReceiverComplete<'a, TickCycle>> Drop for TickCycleHandle<'a, C> {
147 fn drop(&mut self) {
148 assert!(
149 self.completed || std::thread::panicking(),
150 "TickCycleHandle dropped without being completed"
151 );
152 }
153}
154
155#[expect(
156 private_bounds,
157 reason = "only Hydro collections can implement ReceiverComplete"
158)]
159impl<'a, C: ReceiverComplete<'a, TickCycle>> TickCycleHandle<'a, C> {
160 pub fn complete_next_tick(mut self, stream: impl Into<C>) {
164 self.completed = true;
165 C::complete(stream.into(), self.cycle_id, self.expected_location.clone())
166 }
167}
168
169#[doc(hidden)]
172pub trait CompleteCycle<S> {
173 fn complete_next_tick(self, state: S);
175}
176
177impl<'a, C: ReceiverComplete<'a, TickCycle>> CompleteCycle<C> for TickCycleHandle<'a, C> {
178 fn complete_next_tick(self, state: C) {
179 TickCycleHandle::complete_next_tick(self, state)
180 }
181}