windowed_stats/experimental/event/
builder.rs1use std::marker::PhantomData;
6
7use crate::experimental::clock::Timed;
8use crate::experimental::event::Event;
9use crate::experimental::event::reactor::{Context, Reactor};
10use crate::experimental::inspect::{InspectSender, InspectedTimeMatrix, TimeMatrixClient};
11use crate::experimental::series::interpolation::InterpolationKind;
12use crate::experimental::series::statistic::{FoldError, Metadata, SerialStatistic, Statistic};
13use crate::experimental::series::{SamplingProfile, TimeMatrix, TimeMatrixFold};
14
15pub trait Optional {
17 type Field;
18}
19
20#[derive(Clone, Copy, Debug, Default)]
22pub struct Set<T>(PhantomData<fn() -> T>);
23
24impl<T> Optional for Set<T> {
25 type Field = T;
26}
27
28#[derive(Clone, Copy, Debug, Default)]
30pub struct Unset;
31
32impl Optional for Unset {
33 type Field = ();
34}
35
36#[derive(Clone, Copy, Debug)]
45pub struct SampleDataRecord<F, S = (), M = Unset>
46where
47 M: Optional,
48{
49 statistic: F,
50 metadata: M::Field,
51 phantom: PhantomData<fn() -> S>,
52}
53
54impl<F, S, M> SampleDataRecord<F, S, M>
55where
56 M: Optional,
57{
58 fn reactor<T>(
59 matrix: InspectedTimeMatrix<T>,
60 ) -> impl Reactor<T, S, Response = (), Error = FoldError>
61 where
62 T: Clone,
63 {
64 move |event: Timed<Event<T>>, _: Context<'_, S>| {
65 if let Some(sample) = event.to_timed_sample() { matrix.fold_at(sample) } else { Ok(()) }
66 }
67 }
68}
69
70impl<F, S> SampleDataRecord<F, S, Set<Metadata<F>>>
71where
72 F: Statistic,
73{
74 pub fn in_time_matrix<P>(
75 self,
76 client: &TimeMatrixClient,
77 name: impl AsRef<str>,
78 profile: SamplingProfile,
79 interpolation: P::Output<F::Sample>,
80 ) -> impl Reactor<F::Sample, S, Response = (), Error = FoldError>
81 where
82 TimeMatrix<F, P>: 'static + TimeMatrixFold<F::Sample> + Send,
83 Metadata<F>: 'static + Send + Sync,
84 F: SerialStatistic<P>,
85 F::Sample: Send,
86 P: InterpolationKind,
87 {
88 let SampleDataRecord { statistic, metadata, .. } = self;
89 let matrix = client.inspect_time_matrix_with_metadata(
90 name.as_ref(),
91 TimeMatrix::with_statistic(profile, interpolation, statistic),
92 metadata,
93 );
94 Self::reactor(matrix)
95 }
96}
97
98impl<F, S> SampleDataRecord<F, S, Unset>
99where
100 F: Statistic,
101{
102 pub fn with_metadata(
116 self,
117 metadata: impl Into<Metadata<F>>,
118 ) -> SampleDataRecord<F, S, Set<Metadata<F>>> {
119 let SampleDataRecord { statistic, .. } = self;
120 SampleDataRecord { statistic, metadata: metadata.into(), phantom: PhantomData }
121 }
122
123 pub fn in_time_matrix<P>(
124 self,
125 client: &TimeMatrixClient,
126 name: impl AsRef<str>,
127 profile: SamplingProfile,
128 interpolation: P::Output<F::Sample>,
129 ) -> impl Reactor<F::Sample, S, Response = (), Error = FoldError>
130 where
131 TimeMatrix<F, P>: 'static + TimeMatrixFold<F::Sample> + Send,
132 Metadata<F>: 'static + Send + Sync,
133 F: SerialStatistic<P>,
134 F::Sample: Send,
135 P: InterpolationKind,
136 {
137 let SampleDataRecord { statistic, .. } = self;
138 let matrix = client.inspect_time_matrix(
139 name.as_ref(),
140 TimeMatrix::with_statistic(profile, interpolation, statistic),
141 );
142 Self::reactor(matrix)
143 }
144}
145
146pub fn sample_data_record<S, F>(statistic: F) -> SampleDataRecord<F, S, Unset>
154where
155 F: Statistic,
156{
157 SampleDataRecord { statistic, metadata: (), phantom: PhantomData }
158}