rtlola_interpreter/configuration/
config.rs

1//! This module contains all configuration related structures.
2
3use std::marker::PhantomData;
4use std::time::SystemTime;
5
6use rtlola_frontend::RtLolaMir;
7
8use crate::input::{EventFactory, EventFactoryError};
9use crate::monitor::{Incremental, VerdictRepresentation};
10use crate::time::{OutputTimeRepresentation, RealTime, RelativeFloat, TimeRepresentation};
11use crate::Monitor;
12#[cfg(feature = "queued-api")]
13use crate::QueuedMonitor;
14
15/**
16`Config` combines an RTLola specification in [RtLolaMir] form with various configuration parameters for the interpreter.
17
18The configuration describes how the specification should be executed.
19The `Config` can then be turned into a monitor for use via the API or simply executed.
20 */
21#[derive(Clone, Debug)]
22pub struct Config<Mode: ExecutionMode, OutputTime: OutputTimeRepresentation> {
23    /// The representation of the specification
24    pub ir: RtLolaMir,
25    /// In which mode the evaluator is executed
26    pub mode: Mode,
27    /// Which format to use to output time
28    pub output_time_representation: PhantomData<OutputTime>,
29    /// The start time to assume
30    pub start_time: Option<SystemTime>,
31}
32
33/// The execution mode of the interpreter. See the `README` for more details.
34pub trait ExecutionMode: Default {
35    /// The TimeRepresentation used during execution.
36    type SourceTime: TimeRepresentation;
37
38    /// Creates a new ExecutionMode with initíalized Time.
39    fn new(time: Self::SourceTime) -> Self;
40
41    /// Returns the inner TimeRepresentation.
42    fn time_representation(&self) -> &Self::SourceTime;
43}
44
45/// Time is taken by the monitor.
46#[derive(Debug, Clone, Default)]
47pub struct OnlineMode {
48    input_time_representation: RealTime,
49}
50impl ExecutionMode for OnlineMode {
51    type SourceTime = RealTime;
52
53    fn new(time: Self::SourceTime) -> Self {
54        Self {
55            input_time_representation: time,
56        }
57    }
58
59    fn time_representation(&self) -> &Self::SourceTime {
60        &self.input_time_representation
61    }
62}
63
64/// Time is provided by the input source in the format defined by the [TimeRepresentation].
65#[derive(Debug, Copy, Clone, Default)]
66pub struct OfflineMode<InputTime: TimeRepresentation> {
67    input_time_representation: InputTime,
68}
69impl<InputTime: TimeRepresentation> ExecutionMode for OfflineMode<InputTime> {
70    type SourceTime = InputTime;
71
72    fn new(time: Self::SourceTime) -> Self {
73        Self {
74            input_time_representation: time,
75        }
76    }
77
78    fn time_representation(&self) -> &Self::SourceTime {
79        &self.input_time_representation
80    }
81}
82
83/// A configuration struct containing all information (including type information) to initialize a Monitor.
84#[derive(Debug, Clone)]
85pub struct MonitorConfig<Source, Mode, Verdict = Incremental, VerdictTime = RelativeFloat>
86where
87    Source: EventFactory,
88    Mode: ExecutionMode,
89    Verdict: VerdictRepresentation,
90    VerdictTime: OutputTimeRepresentation,
91{
92    config: Config<Mode, VerdictTime>,
93    input: PhantomData<Source>,
94    verdict: PhantomData<Verdict>,
95}
96
97impl<
98        Source: EventFactory + 'static,
99        Mode: ExecutionMode,
100        Verdict: VerdictRepresentation,
101        VerdictTime: OutputTimeRepresentation,
102    > MonitorConfig<Source, Mode, Verdict, VerdictTime>
103{
104    /// Creates a new monitor config from a config
105    pub fn new(config: Config<Mode, VerdictTime>) -> Self {
106        Self {
107            config,
108            input: PhantomData,
109            verdict: PhantomData,
110        }
111    }
112
113    /// Returns the underlying configuration
114    pub fn inner(&self) -> &Config<Mode, VerdictTime> {
115        &self.config
116    }
117
118    /// Transforms the configuration into a [Monitor] using the provided data to setup the input source.
119    pub fn monitor_with_data(
120        self,
121        data: Source::CreationData,
122    ) -> Result<Monitor<Source, Mode, Verdict, VerdictTime>, EventFactoryError> {
123        Monitor::setup(self.config, data)
124    }
125
126    /// Transforms the configuration into a [Monitor]
127    pub fn monitor(self) -> Result<Monitor<Source, Mode, Verdict, VerdictTime>, EventFactoryError>
128    where
129        Source: EventFactory<CreationData = ()>,
130    {
131        Monitor::setup(self.config, ())
132    }
133}
134
135#[cfg(feature = "queued-api")]
136impl<
137        Source: EventFactory + 'static,
138        SourceTime: TimeRepresentation,
139        Verdict: VerdictRepresentation,
140        VerdictTime: OutputTimeRepresentation,
141    > MonitorConfig<Source, OfflineMode<SourceTime>, Verdict, VerdictTime>
142{
143    /// Transforms the configuration into a [QueuedMonitor] using the provided data to setup the input source.
144    pub fn queued_monitor_with_data(
145        self,
146        data: Source::CreationData,
147    ) -> QueuedMonitor<Source, OfflineMode<SourceTime>, Verdict, VerdictTime> {
148        <QueuedMonitor<Source, OfflineMode<SourceTime>, Verdict, VerdictTime>>::setup(
149            self.config,
150            data,
151        )
152    }
153
154    /// Transforms the configuration into a [QueuedMonitor]
155    pub fn queued_monitor(
156        self,
157    ) -> QueuedMonitor<Source, OfflineMode<SourceTime>, Verdict, VerdictTime>
158    where
159        Source: EventFactory<CreationData = ()>,
160    {
161        <QueuedMonitor<Source, OfflineMode<SourceTime>, Verdict, VerdictTime>>::setup(
162            self.config,
163            (),
164        )
165    }
166}
167
168#[cfg(feature = "queued-api")]
169impl<
170        Source: EventFactory + 'static,
171        Verdict: VerdictRepresentation,
172        VerdictTime: OutputTimeRepresentation,
173    > MonitorConfig<Source, OnlineMode, Verdict, VerdictTime>
174{
175    /// Transforms the configuration into a [QueuedMonitor] using the provided data to setup the input source.
176    pub fn queued_monitor_with_data(
177        self,
178        data: Source::CreationData,
179    ) -> QueuedMonitor<Source, OnlineMode, Verdict, VerdictTime> {
180        <QueuedMonitor<Source, OnlineMode, Verdict, VerdictTime>>::setup(self.config, data)
181    }
182
183    /// Transforms the configuration into a [QueuedMonitor]
184    pub fn queued_monitor(self) -> QueuedMonitor<Source, OnlineMode, Verdict, VerdictTime>
185    where
186        Source: EventFactory<CreationData = ()>,
187    {
188        <QueuedMonitor<Source, OnlineMode, Verdict, VerdictTime>>::setup(self.config, ())
189    }
190}
191
192impl Config<OfflineMode<RelativeFloat>, RelativeFloat> {
193    /// Creates a new Debug config.
194    pub fn debug(ir: RtLolaMir) -> Self {
195        Config {
196            ir,
197            mode: OfflineMode::default(),
198            output_time_representation: PhantomData,
199            start_time: None,
200        }
201    }
202}
203
204impl<Mode: ExecutionMode, OutputTime: OutputTimeRepresentation> Config<Mode, OutputTime> {
205    /// Creates a new API config
206    pub fn api(ir: RtLolaMir) -> Config<OfflineMode<RelativeFloat>, OutputTime> {
207        Config {
208            ir,
209            mode: OfflineMode::default(),
210            output_time_representation: PhantomData,
211            start_time: None,
212        }
213    }
214
215    /// Turn the configuration into the [Monitor] API.
216    pub fn monitor<Source: EventFactory, Verdict: VerdictRepresentation>(
217        self,
218        data: Source::CreationData,
219    ) -> Result<Monitor<Source, Mode, Verdict, OutputTime>, EventFactoryError> {
220        Monitor::setup(self, data)
221    }
222}