hydro_lang/
cycle.rs

1use crate::location::{Location, LocationId};
2use crate::staging_util::Invariant;
3
4pub enum ForwardRefMarker {}
5pub enum TickCycleMarker {}
6
7pub trait DeferTick {
8    fn defer_tick(self) -> Self;
9}
10
11pub trait CycleComplete<'a, T> {
12    fn complete(self, ident: syn::Ident, expected_location: LocationId);
13}
14
15pub trait CycleCollection<'a, T>: CycleComplete<'a, T> {
16    type Location: Location<'a>;
17
18    fn create_source(ident: syn::Ident, location: Self::Location) -> Self;
19}
20
21pub trait CycleCollectionWithInitial<'a, T>: CycleComplete<'a, T> {
22    type Location: Location<'a>;
23
24    fn create_source(ident: syn::Ident, initial: Self, location: Self::Location) -> Self;
25}
26
27/// Represents a forward reference in the graph that will be fulfilled
28/// by a stream that is not yet known.
29///
30/// See [`crate::FlowBuilder`] for an explainer on the type parameters.
31pub struct ForwardRef<'a, S: CycleComplete<'a, ForwardRefMarker>> {
32    pub(crate) completed: bool,
33    pub(crate) ident: syn::Ident,
34    pub(crate) expected_location: LocationId,
35    pub(crate) _phantom: Invariant<'a, S>,
36}
37
38impl<'a, S: CycleComplete<'a, ForwardRefMarker>> Drop for ForwardRef<'a, S> {
39    fn drop(&mut self) {
40        if !self.completed {
41            panic!("ForwardRef dropped without being completed");
42        }
43    }
44}
45
46impl<'a, S: CycleComplete<'a, ForwardRefMarker>> ForwardRef<'a, S> {
47    pub fn complete(mut self, stream: S) {
48        self.completed = true;
49        let ident = self.ident.clone();
50        S::complete(stream, ident, self.expected_location.clone())
51    }
52}
53
54pub struct TickCycle<'a, S: CycleComplete<'a, TickCycleMarker> + DeferTick> {
55    pub(crate) completed: bool,
56    pub(crate) ident: syn::Ident,
57    pub(crate) expected_location: LocationId,
58    pub(crate) _phantom: Invariant<'a, S>,
59}
60
61impl<'a, S: CycleComplete<'a, TickCycleMarker> + DeferTick> Drop for TickCycle<'a, S> {
62    fn drop(&mut self) {
63        if !self.completed {
64            panic!("TickCycle dropped without being completed");
65        }
66    }
67}
68
69impl<'a, S: CycleComplete<'a, TickCycleMarker> + DeferTick> TickCycle<'a, S> {
70    pub fn complete_next_tick(mut self, stream: S) {
71        self.completed = true;
72        let ident = self.ident.clone();
73        S::complete(stream.defer_tick(), ident, self.expected_location.clone())
74    }
75}