Skip to main content

harmos_domain/streams/
mod.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10/* === Modules === */
11
12/* === Re-Exports === */
13
14/* === Imports === */
15
16// Standard Library Imports
17use std::any::{Any, TypeId};
18use std::hash::Hash;
19use std::sync::Arc;
20// Third Party Imports
21use serde::Serialize;
22use serde::de::DeserializeOwned;
23// Local Imports
24
25/* === Constants === */
26
27/* === Macros === */
28
29macro_rules! prefix {
30    (($($whole:ident),+) selects ($($taken:ident),+) at ($($at:tt),+)) => {
31        impl<$($whole: Track),+> Prefix<($($whole,)+)> for ($($taken,)+) {
32            fn labels(&self) -> Vec<String> {
33                vec![$(self.$at.label()),+]
34            }
35
36            fn selects(&self, whole: &($($whole,)+)) -> bool {
37                $(self.$at == whole.$at)&&+
38            }
39        }
40    };
41}
42
43prefix!((A) selects (A) at (0));
44
45prefix!((A, B) selects (A) at (0));
46
47prefix!((A, B) selects (A, B) at (0, 1));
48
49prefix!((A, B, C) selects (A) at (0));
50
51prefix!((A, B, C) selects (A, B) at (0, 1));
52
53prefix!((A, B, C) selects (A, B, C) at (0, 1, 2));
54
55prefix!((A, B, C, D) selects (A) at (0));
56
57prefix!((A, B, C, D) selects (A, B) at (0, 1));
58
59prefix!((A, B, C, D) selects (A, B, C) at (0, 1, 2));
60
61prefix!((A, B, C, D) selects (A, B, C, D) at (0, 1, 2, 3));
62
63/* === Type Aliases === */
64
65/* === Structs === */
66
67#[derive(Clone, Debug)]
68// A declaration is a value an application *states*; only the host core reads
69// what it states. In an authoring build there is no host core, so these fields
70// are written and never read — which is the shape of the thing, not a loose
71// end.
72
73pub struct Definition {
74    metadata: crate::Metadata,
75    row_metadata: Vec<crate::StreamField>,
76    id: Arc<str>,
77    version: u32,
78    window: usize,
79    row: TypeId,
80    batch: Option<BatchDefinition>,
81    owner: Option<Arc<str>>,
82    schema: Option<Arc<crate::schema::graph::Schema>>,
83}
84
85#[derive(Clone, Copy, Debug)]
86
87pub struct BatchDefinition {
88    samples: u64,
89    fields: &'static [&'static str],
90    measure: fn(&dyn Any, &mut dyn FnMut(f64)),
91}
92
93/* === Enums === */
94
95/* === Traits === */
96
97pub trait StreamRow: Clone + Send + Sync + Serialize + DeserializeOwned + 'static {
98    const ID: &'static str;
99    const VERSION: u32;
100    const WINDOW: usize;
101    fn metadata() -> crate::Metadata {
102        crate::Metadata::new(crate::Identifier::declared(Self::ID, "stream"), Self::ID, None)
103    }
104    fn row_metadata() -> Vec<crate::StreamField> {
105        Vec::new()
106    }
107    fn batch_definition() -> Option<BatchDefinition> {
108        None
109    }
110}
111
112pub trait StreamCatalog<S: StreamRow> {}
113
114pub trait Track: Clone + Eq + Hash + Send + Sync + 'static {
115    fn label(&self) -> String;
116}
117
118pub trait Prefix<T>: Clone + Send + Sync + 'static {
119    fn labels(&self) -> Vec<String>;
120
121    fn selects(&self, whole: &T) -> bool;
122}
123
124pub trait Tracked {
125    const TRACK: &'static [&'static str];
126
127    type Track: Prefix<Self::Track>;
128
129    fn track(&self) -> Self::Track;
130}
131
132pub trait Axial {
133    const AXIS: &'static str;
134
135    fn axis(&self) -> u64;
136}
137
138pub trait Batched: 'static {
139    const SAMPLES: u64;
140    const MEASURES: &'static [&'static str];
141
142    fn measure(&self, visit: &mut dyn FnMut(f64));
143}
144
145/* === Implementations === */
146
147impl Definition {
148    pub fn row(&self) -> TypeId {
149        self.row
150    }
151
152    pub fn batch(&self) -> Option<BatchDefinition> {
153        self.batch
154    }
155
156    pub fn publication(mut self, owner: impl Into<Arc<str>>, schema: impl Into<Arc<crate::schema::graph::Schema>>) -> Self {
157        self.owner = Some(owner.into());
158        self.schema = Some(schema.into());
159        self
160    }
161
162    pub fn declared<S: 'static>(id: impl Into<Arc<str>>, version: u32, window: usize) -> Self {
163        let id = id.into();
164        Self {
165            metadata: crate::Metadata::new(crate::Identifier::declared(id.as_ref(), "stream"), id.as_ref(), None),
166            row_metadata: Vec::new(),
167            id,
168            version,
169            window,
170            row: TypeId::of::<S>(),
171            batch: None,
172            owner: None,
173            schema: None,
174        }
175    }
176
177    pub fn batching(mut self, batch: Option<BatchDefinition>) -> Self {
178        self.batch = batch;
179        self
180    }
181
182    pub fn presentation(mut self, metadata: crate::Metadata, rows: Vec<crate::StreamField>) -> Self {
183        self.metadata = metadata;
184        self.row_metadata = rows;
185        self
186    }
187
188    pub fn metadata(&self) -> &crate::Metadata {
189        &self.metadata
190    }
191
192    pub fn row_metadata(&self) -> &[crate::StreamField] {
193        &self.row_metadata
194    }
195
196    pub fn id(&self) -> &str {
197        &self.id
198    }
199
200    pub fn owner(&self) -> Option<&str> {
201        self.owner.as_deref()
202    }
203
204    pub fn schema(&self) -> Option<&crate::schema::graph::Schema> {
205        self.schema.as_deref()
206    }
207
208    pub fn version(&self) -> u32 {
209        self.version
210    }
211
212    pub fn window(&self) -> usize {
213        self.window
214    }
215}
216
217impl BatchDefinition {
218    pub fn samples(&self) -> u64 {
219        self.samples
220    }
221
222    pub fn fields(&self) -> &'static [&'static str] {
223        self.fields
224    }
225
226    pub fn measure(&self, row: &dyn Any, visit: &mut dyn FnMut(f64)) {
227        (self.measure)(row, visit);
228    }
229
230    pub fn of<S: Batched>() -> Self {
231        assert!(S::SAMPLES > 0 && !S::MEASURES.is_empty(), "a batch needs samples and measured fields");
232        Self {
233            samples: S::SAMPLES,
234            fields: S::MEASURES,
235            measure: |row, visit| row.downcast_ref::<S>().expect("declared stream row").measure(visit),
236        }
237    }
238}
239
240/* === Public Functions === */
241
242/* === Private Functions === */
243
244/* === Tests === */