hydro_lang/
cycle.rs

1use sealed::sealed;
2
3use crate::location::{Location, LocationId};
4use crate::staging_util::Invariant;
5
6#[sealed]
7pub trait CycleMarker {}
8
9pub enum ForwardRefMarker {}
10
11#[sealed]
12impl CycleMarker for ForwardRefMarker {}
13
14pub enum TickCycleMarker {}
15
16#[sealed]
17impl CycleMarker for TickCycleMarker {}
18
19pub trait DeferTick {
20    fn defer_tick(self) -> Self;
21}
22
23pub trait CycleComplete<'a, Marker>
24where
25    Marker: CycleMarker,
26{
27    fn complete(self, ident: syn::Ident, expected_location: LocationId);
28}
29
30pub trait CycleCollection<'a, Marker>: CycleComplete<'a, Marker>
31where
32    Marker: CycleMarker,
33{
34    type Location: Location<'a>;
35
36    fn create_source(ident: syn::Ident, location: Self::Location) -> Self;
37}
38
39pub trait CycleCollectionWithInitial<'a, Marker>: CycleComplete<'a, Marker>
40where
41    Marker: CycleMarker,
42{
43    type Location: Location<'a>;
44
45    fn create_source(ident: syn::Ident, initial: Self, location: Self::Location) -> Self;
46}
47
48/// Represents a forward reference in the graph that will be fulfilled
49/// by a stream that is not yet known.
50///
51/// See [`crate::FlowBuilder`] for an explainer on the type parameters.
52pub struct ForwardRef<'a, Stream>
53where
54    Stream: CycleComplete<'a, ForwardRefMarker>,
55{
56    pub(crate) completed: bool,
57    pub(crate) ident: syn::Ident,
58    pub(crate) expected_location: LocationId,
59    pub(crate) _phantom: Invariant<'a, Stream>,
60}
61
62impl<'a, S> Drop for ForwardRef<'a, S>
63where
64    S: CycleComplete<'a, ForwardRefMarker>,
65{
66    fn drop(&mut self) {
67        if !self.completed {
68            panic!("ForwardRef dropped without being completed");
69        }
70    }
71}
72
73impl<'a, S> ForwardRef<'a, S>
74where
75    S: CycleComplete<'a, ForwardRefMarker>,
76{
77    pub fn complete(mut self, stream: S) {
78        self.completed = true;
79        let ident = self.ident.clone();
80        S::complete(stream, ident, self.expected_location.clone())
81    }
82}
83
84pub struct TickCycle<'a, Stream>
85where
86    Stream: CycleComplete<'a, TickCycleMarker> + DeferTick,
87{
88    pub(crate) completed: bool,
89    pub(crate) ident: syn::Ident,
90    pub(crate) expected_location: LocationId,
91    pub(crate) _phantom: Invariant<'a, Stream>,
92}
93
94impl<'a, S> Drop for TickCycle<'a, S>
95where
96    S: CycleComplete<'a, TickCycleMarker> + DeferTick,
97{
98    fn drop(&mut self) {
99        if !self.completed {
100            panic!("TickCycle dropped without being completed");
101        }
102    }
103}
104
105impl<'a, S> TickCycle<'a, S>
106where
107    S: CycleComplete<'a, TickCycleMarker> + DeferTick,
108{
109    pub fn complete_next_tick(mut self, stream: S) {
110        self.completed = true;
111        let ident = self.ident.clone();
112        S::complete(stream.defer_tick(), ident, self.expected_location.clone())
113    }
114}