1use std::any::{Any, TypeId};
18use std::hash::Hash;
19use std::sync::Arc;
20use serde::Serialize;
22use serde::de::DeserializeOwned;
23macro_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#[derive(Clone, Debug)]
68pub 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
93pub 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
145impl 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