1use std::ops::Deref;
3
4use miette::SourceSpan;
5use serde::{Deserialize, Serialize};
6pub use strumbra::Error as StrumbraError;
7use strumbra::SharedString;
8
9use crate::{
10 linker::{Arg, ArgType, FunctionTrait},
11 query::ParamDeclaration,
12};
13
14#[derive(
16 Debug,
17 Clone,
18 PartialEq,
19 Eq,
20 Hash,
21 serde::Serialize,
23 serde::Deserialize,
24)]
25#[cfg_attr(feature = "bincode", derive(bincode::Decode, bincode::Encode))]
26pub struct Dataset(String);
27
28impl From<&str> for Dataset {
29 fn from(value: &str) -> Self {
30 Dataset(value.to_string())
31 }
32}
33impl PartialEq<str> for Dataset {
34 fn eq(&self, other: &str) -> bool {
35 self.0 == *other
36 }
37}
38
39impl PartialEq<&str> for Dataset {
40 fn eq(&self, other: &&str) -> bool {
41 &*self.0 == *other
42 }
43}
44
45impl Dataset {
46 #[must_use]
48 pub fn new(name: String) -> Self {
49 Self(name)
50 }
51}
52
53impl Deref for Dataset {
54 type Target = String;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl std::fmt::Display for Dataset {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 self.0.fmt(f)
64 }
65}
66
67#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
69pub enum Parameterized<T> {
70 Concrete(T),
72 Param {
74 span: SourceSpan,
76 param: ParamDeclaration,
78 },
79}
80
81impl<T> std::fmt::Display for Parameterized<T>
82where
83 T: std::fmt::Display,
84{
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 match self {
87 Parameterized::Concrete(inner) => write!(f, "{inner}"),
88 Parameterized::Param { span: _, param } => write!(f, "${}", param.name),
89 }
90 }
91}
92
93impl<T> Parameterized<T> {
94 pub fn map_concrete<O, F: Fn(T) -> O>(self, f: F) -> Parameterized<O> {
96 match self {
97 Parameterized::Concrete(inner) => Parameterized::Concrete(f(inner)),
98 Parameterized::Param { span, param } => Parameterized::Param { span, param },
99 }
100 }
101
102 pub fn try_map_concrete<O, E, F: Fn(T) -> Result<O, E>>(
104 self,
105 f: F,
106 ) -> Result<Parameterized<O>, E> {
107 Ok(match self {
108 Parameterized::Concrete(inner) => Parameterized::Concrete(f(inner)?),
109 Parameterized::Param { span, param } => Parameterized::Param { span, param },
110 })
111 }
112
113 pub fn is_param(&self) -> bool {
115 matches!(self, Parameterized::Param { .. })
116 }
117
118 pub fn is_concrete(&self) -> bool {
120 matches!(self, Parameterized::Concrete(_))
121 }
122}
123
124#[derive(
126 Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Deserialize, serde::Serialize,
127)]
128#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
129pub struct Metric(#[cfg_attr(feature = "bincode", bincode(with_serde))] SharedString);
130
131impl std::fmt::Display for Metric {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 self.0.fmt(f)
134 }
135}
136
137impl PartialEq<str> for Metric {
138 fn eq(&self, other: &str) -> bool {
139 &*self.0 == other
140 }
141}
142
143impl Deref for Metric {
144 type Target = str;
145
146 fn deref(&self) -> &Self::Target {
147 &self.0
148 }
149}
150
151impl Metric {
152 pub fn new(name: &str) -> Result<Self, StrumbraError> {
154 Ok(Self(SharedString::try_from(name)?))
155 }
156}
157
158impl TryFrom<String> for Metric {
159 type Error = StrumbraError;
160
161 fn try_from(s: String) -> Result<Self, Self::Error> {
162 Ok(Metric(SharedString::try_from(s)?))
163 }
164}
165
166impl TryFrom<&'_ str> for Metric {
167 type Error = StrumbraError;
168
169 fn try_from(s: &str) -> Result<Self, Self::Error> {
170 Ok(Metric(SharedString::try_from(s)?))
171 }
172}
173
174impl PartialEq<&str> for Metric {
175 fn eq(&self, other: &&str) -> bool {
176 &*self.0 == *other
177 }
178}
179
180#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)]
182#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
183pub enum ConversionMethod {
184 #[default]
186 Rate,
187 Increase,
189}
190
191impl std::fmt::Display for ConversionMethod {
192 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193 match self {
194 ConversionMethod::Rate => write!(f, "rate"),
195 ConversionMethod::Increase => write!(f, "increase"),
196 }
197 }
198}
199
200#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
202pub enum BucketType {
203 Histogram,
205 InterpolateDeltaHistogram,
207 InterpolateCumulativeHistogram(ConversionMethod),
209}
210
211impl FunctionTrait for BucketType {
212 fn doc(&self) -> &str {
213 match self {
214 BucketType::Histogram => {
215 "Aggregates non-histogram input series using the provided bucket specs (including histogram quantile calculation)."
216 }
217 BucketType::InterpolateDeltaHistogram => {
218 "Aggregates delta-temporality histogram input series using the provided bucket specs (including histogram quantile calculation via interpolation)."
219 }
220 BucketType::InterpolateCumulativeHistogram(_) => {
221 "Aggregates cumulative-temporality histogram input series after converting to delta using a conversion mode (including histogram quantile calculation via interpolation)."
222 }
223 }
224 }
225
226 fn args(&self) -> Vec<Arg> {
227 match self {
228 BucketType::InterpolateCumulativeHistogram(_) => vec![
229 Arg::new("mode", ArgType::Enum(&["rate", "increase"])),
230 Arg::new(
231 "specs",
232 ArgType::Repeated {
233 typ: Box::new(ArgType::OneOf(vec![
234 ArgType::Enum(&["count", "avg", "sum"]),
236 ArgType::Float,
237 ])),
238 min: 1,
239 max: None,
240 },
241 ),
242 ],
243 BucketType::Histogram | BucketType::InterpolateDeltaHistogram => vec![Arg::new(
244 "specs",
245 ArgType::Repeated {
246 typ: Box::new(ArgType::OneOf(vec![
247 ArgType::Enum(&["count", "avg", "sum", "min", "max"]),
248 ArgType::Float,
249 ])),
250 min: 1,
251 max: None,
252 },
253 )],
254 }
255 }
256}
257
258impl std::fmt::Display for BucketType {
259 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260 match self {
261 BucketType::Histogram => write!(f, "histogram"),
262 BucketType::InterpolateDeltaHistogram => write!(f, "interpolate_delta_histogram"),
263 BucketType::InterpolateCumulativeHistogram(_) => {
264 write!(f, "interpolate_cumulative_histogram")
265 }
266 }
267 }
268}
269
270#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
272pub enum MapType {
273 Min,
275 Max,
277 Rate,
279 Add,
281 Sub,
283 Mul,
285 Div,
287 Abs,
289 FillConst,
291 FillPrev,
293 Increase,
295 FilterLt,
297 FilterGt,
299 FilterEq,
301 FilterNe,
303 FilterGe,
305 FilterLe,
307 IsLt,
309 IsGt,
311 IsEq,
313 IsNe,
315 IsGe,
317 IsLe,
319 InterpolateLinear,
321}
322
323impl FunctionTrait for MapType {
324 fn doc(&self) -> &str {
325 match self {
326 MapType::Min => "Minimum between the argument and the datapoint",
327 MapType::Max => "Maximum between the argument and the datapoint",
328 MapType::Add => "Adds the argument to the datapoint",
329 MapType::Sub => "Subtracts the argument from the datapoint",
330 MapType::Mul => "Multiplies the argument with the datapoint",
331 MapType::Div => "Divides the datapoint by the argument",
332 MapType::Abs => "Absolute value of the datapoint",
333 MapType::Rate => {
334 "Per second rate of change between the datapoint and the previous datapoint"
335 }
336 MapType::FillConst => "Fills unset datapoints with the given constant",
337 MapType::FillPrev => "Fills unset datapoints with the previous datapoint",
338 MapType::Increase => {
339 "Calculates the increase between the datapoint and the previous datapoint"
340 }
341 MapType::FilterLt => {
342 "Filters for datapoints that are less than the argument all datapoints not less than the argument are removed"
343 }
344 MapType::FilterGt => {
345 "Filters for datapoints that are greater than the argument all datapoints not greater than the argument are removed"
346 }
347 MapType::FilterEq => {
348 "Filters for datapoints that are equal to the argument all datapoints not equal to the argument are removed"
349 }
350 MapType::FilterNe => {
351 "Filters for datapoints that are not equal to the argument all datapoints equal to the argument are removed"
352 }
353 MapType::FilterGe => {
354 "Filters for datapoints that are greater than or equal to the argument all datapoints not greater than or equal to the argument are removed"
355 }
356 MapType::FilterLe => {
357 "Filters for datapoints that are less than or equal to the argument all datapoints not less than or equal to the argument are removed"
358 }
359 MapType::IsLt => {
360 "Sets the datapoint to 1.0 if the datapoint is less than the argument otherwise sets it to 0.0"
361 }
362 MapType::IsGt => {
363 "Sets the datapoint to 1.0 if the datapoint is greater than the argument otherwise sets it to 0.0"
364 }
365 MapType::IsEq => {
366 "Sets the datapoint to 1.0 if the datapoint is equal to the argument otherwise sets it to 0.0"
367 }
368 MapType::IsNe => {
369 "Sets the datapoint to 1.0 if the datapoint is not equal to the argument otherwise sets it to 0.0"
370 }
371 MapType::IsLe => {
372 "Sets the datapoint to 1.0 if the datapoint is less than or equal to the argument otherwise sets it to 0.0"
373 }
374 MapType::IsGe => {
375 "Sets the datapoint to 1.0 if the datapoint is greater than or equal to the argument otherwise sets it to 0.0"
376 }
377 MapType::InterpolateLinear => {
378 "Performs linear interpolation between two datapoints filling unset values with the interpolated value"
379 }
380 }
381 }
382 fn args(&self) -> Vec<Arg> {
383 match self {
384 MapType::FilterLt
385 | MapType::FilterGt
386 | MapType::FilterEq
387 | MapType::FilterNe
388 | MapType::FilterGe
389 | MapType::FilterLe
390 | MapType::IsLt
391 | MapType::IsGt
392 | MapType::IsEq
393 | MapType::IsNe
394 | MapType::IsGe
395 | MapType::IsLe
396 | MapType::Add
397 | MapType::Sub
398 | MapType::Mul
399 | MapType::Div
400 | MapType::FillConst => vec![Arg::new("value", ArgType::Float)],
401 MapType::Min => vec![Arg::new("min", ArgType::Float)],
402 MapType::Max => vec![Arg::new("max", ArgType::Float)],
403 MapType::Abs
404 | MapType::Rate
405 | MapType::FillPrev
406 | MapType::Increase
407 | MapType::InterpolateLinear => {
408 vec![]
409 }
410 }
411 }
412}
413
414impl std::fmt::Display for MapType {
415 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
416 match self {
417 MapType::Min => write!(f, "min"),
418 MapType::Max => write!(f, "max"),
419 MapType::Rate => write!(f, "rate"),
420 MapType::Add => write!(f, "+"),
421 MapType::Sub => write!(f, "-"),
422 MapType::Mul => write!(f, "*"),
423 MapType::Div => write!(f, "/"),
424 MapType::Abs => write!(f, "abs"),
425 MapType::FillConst => write!(f, "fill::const"),
426 MapType::FillPrev => write!(f, "fill::prev"),
427 MapType::Increase => write!(f, "increase"),
428 MapType::FilterLt => write!(f, "filter::lt"),
429 MapType::FilterGt => write!(f, "filter::gt"),
430 MapType::FilterEq => write!(f, "filter::eq"),
431 MapType::FilterNe => write!(f, "filter::ne"),
432 MapType::FilterGe => write!(f, "filter::ge"),
433 MapType::FilterLe => write!(f, "filter::le"),
434 MapType::IsLt => write!(f, "Is::lt"),
435 MapType::IsGt => write!(f, "Is::gt"),
436 MapType::IsEq => write!(f, "Is::eq"),
437 MapType::IsNe => write!(f, "Is::ne"),
438 MapType::IsGe => write!(f, "Is::ge"),
439 MapType::IsLe => write!(f, "Is::le"),
440 MapType::InterpolateLinear => write!(f, "linear"),
441 }
442 }
443}
444
445#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
447pub enum TimeType {
448 Count,
450 Sum,
452 Avg,
454 Min,
456 Max,
458 Rate,
460 Last,
462}
463impl FunctionTrait for TimeType {
464 fn doc(&self) -> &str {
465 match self {
466 TimeType::Count => "Count the number of elements",
467 TimeType::Sum => "Sum the elements",
468 TimeType::Avg => "Average the elements",
469 TimeType::Min => "Minimum of the elements",
470 TimeType::Max => "Maximum of the elements",
471 TimeType::Rate => "Average per second rate over a time window",
472 TimeType::Last => "Last observed value",
473 }
474 }
475
476 fn args(&self) -> Vec<Arg> {
477 vec![]
478 }
479}
480
481impl std::fmt::Display for TimeType {
482 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
483 match self {
484 TimeType::Count => write!(f, "count"),
485 TimeType::Sum => write!(f, "sum"),
486 TimeType::Avg => write!(f, "avg"),
487 TimeType::Min => write!(f, "min"),
488 TimeType::Max => write!(f, "max"),
489 TimeType::Rate => write!(f, "prom::rate"),
490 TimeType::Last => write!(f, "last"),
491 }
492 }
493}
494
495#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
497pub enum TagsType {
498 Count,
500 Sum,
502 Avg,
504 Min,
506 Max,
508}
509
510impl FunctionTrait for TagsType {
511 fn doc(&self) -> &str {
512 match self {
513 TagsType::Count => "Counts the number of set values",
514 TagsType::Sum => "Sums the datapoints",
515 TagsType::Avg => "Averages the datapoints",
516 TagsType::Min => "The minimum value",
517 TagsType::Max => "The maximum value",
518 }
519 }
520 fn args(&self) -> Vec<Arg> {
521 match self {
522 TagsType::Count | TagsType::Sum | TagsType::Avg | TagsType::Min | TagsType::Max => {
523 vec![]
524 }
525 }
526 }
527}
528
529impl std::fmt::Display for TagsType {
530 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531 match self {
532 TagsType::Count => write!(f, "count"),
533 TagsType::Sum => write!(f, "sum"),
534 TagsType::Avg => write!(f, "avg"),
535 TagsType::Min => write!(f, "min"),
536 TagsType::Max => write!(f, "max"),
537 }
538 }
539}
540
541#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
543pub enum ComputeType {
544 Avg,
546 Min,
548 Max,
550 Add,
552 Sub,
554 Mul,
556 Div,
558}
559
560impl FunctionTrait for ComputeType {
561 fn doc(&self) -> &str {
562 match self {
563 ComputeType::Add => "Sums the datapoints",
564 ComputeType::Avg => "Averages the datapoints",
565 ComputeType::Min => "The minimum value",
566 ComputeType::Max => "The maximum value",
567 ComputeType::Div => "Divides the datapoints, removes datapoints if the divisor is zero",
568 ComputeType::Mul => "Multiplies the datapoints",
569 ComputeType::Sub => "Subtracts the datapoints",
570 }
571 }
572 fn args(&self) -> Vec<Arg> {
573 match self {
574 ComputeType::Add
575 | ComputeType::Avg
576 | ComputeType::Min
577 | ComputeType::Max
578 | ComputeType::Div
579 | ComputeType::Mul
580 | ComputeType::Sub => vec![],
581 }
582 }
583}
584
585impl std::fmt::Display for ComputeType {
586 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
587 match self {
588 ComputeType::Avg => write!(f, "avg"),
589 ComputeType::Min => write!(f, "min"),
590 ComputeType::Max => write!(f, "max"),
591 ComputeType::Div => write!(f, "/"),
592 ComputeType::Mul => write!(f, "*"),
593 ComputeType::Add => write!(f, "+"),
594 ComputeType::Sub => write!(f, "-"),
595 }
596 }
597}
598
599#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)]
601#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
602pub enum BucketSpec {
603 #[default]
605 Count,
606 Avg,
608 Sum,
610 Min,
612 Max,
614 Percentile(f64),
616}
617
618impl std::fmt::Display for BucketSpec {
619 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
620 match self {
621 BucketSpec::Count => write!(f, "count"),
622 BucketSpec::Avg => write!(f, "avg"),
623 BucketSpec::Sum => write!(f, "sum"),
624 BucketSpec::Min => write!(f, "min"),
625 BucketSpec::Max => write!(f, "max"),
626 BucketSpec::Percentile(p) => write!(f, "{p}"),
627 }
628 }
629}