hydro_lang/
runtime_context.rs

1//! Interfaces to access DFIR runtime metadata from Hydro programs.
2
3use dfir_rs::scheduled::context::Context;
4use quote::quote;
5use stageleft::runtime_support::{FreeVariableWithContextWithProps, QuoteTokens};
6
7use crate::location::Location;
8
9/// Exposes the DFIR [`Context`] inside quoted code.
10pub static RUNTIME_CONTEXT: RuntimeContext = RuntimeContext { _private: &() };
11
12/// A handle to DFIR [`Context`] which can be used inside quoted code.
13///
14/// When spliced, it turns into a reference to [`Context`].
15#[derive(Clone, Copy)]
16pub struct RuntimeContext<'a> {
17    _private: &'a (),
18}
19
20impl<'a, L> FreeVariableWithContextWithProps<L, ()> for RuntimeContext<'a>
21where
22    L: Location<'a>,
23{
24    type O = &'a Context;
25
26    fn to_tokens(self, _ctx: &L) -> (QuoteTokens, ()) {
27        (
28            QuoteTokens {
29                prelude: None,
30                expr: Some(quote!(&context)),
31            },
32            (),
33        )
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use futures::StreamExt;
40    use hydro_deploy::Deployment;
41    use stageleft::q;
42
43    use super::RUNTIME_CONTEXT;
44    use crate::compile::builder::FlowBuilder;
45    use crate::location::Location;
46
47    struct P1 {}
48
49    #[tokio::test]
50    async fn runtime_context() {
51        let mut deployment = Deployment::new();
52
53        let flow = FlowBuilder::new();
54        let node = flow.process::<P1>();
55        let external = flow.external::<()>();
56
57        let out_port = node
58            .source_iter(q!(0..5))
59            .map(q!(|v| (v, RUNTIME_CONTEXT.current_tick().0)))
60            .send_bincode_external(&external);
61
62        let nodes = flow
63            .with_process(&node, deployment.Localhost())
64            .with_external(&external, deployment.Localhost())
65            .deploy(&mut deployment);
66
67        deployment.deploy().await.unwrap();
68
69        let mut external_out = nodes.connect(out_port).await;
70
71        deployment.start().await.unwrap();
72
73        for i in 0..5 {
74            assert_eq!(external_out.next().await.unwrap(), (i, 0));
75        }
76    }
77}