1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_with::skip_serializing_none;
5
6use crate::{AdvancedFilter, PropertyIdentifier};
7
8use super::LastUpdatedTimeFilter;
9
10#[skip_serializing_none]
11#[derive(Debug, Default, Clone, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct Bounds<T> {
15 pub min: Option<T>,
17 pub max: Option<T>,
19}
20
21#[skip_serializing_none]
22#[derive(Debug, Default, Clone, Serialize, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct SimpleAggregate {
26 pub property: Vec<String>,
28}
29
30#[skip_serializing_none]
31#[derive(Debug, Default, Clone, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct UniqueValuesAggregate {
35 pub property: Vec<String>,
37 pub aggregates: Option<HashMap<String, RecordsAggregate>>,
39 pub size: Option<u32>,
41}
42
43#[skip_serializing_none]
44#[derive(Debug, Default, Clone, Serialize, Deserialize)]
45#[serde(rename_all = "camelCase")]
46pub struct NumberHistogramAggregate {
49 pub property: Vec<String>,
51 pub hard_bounds: Option<Bounds<f64>>,
56 pub interval: f64,
58 pub aggregates: Option<HashMap<String, RecordsAggregate>>,
60}
61
62#[derive(Serialize, Deserialize, Clone, Debug)]
63pub enum CalendarInterval {
65 #[serde(rename = "1y")]
66 Year,
68 #[serde(rename = "1q")]
69 Quarter,
71 #[serde(rename = "1M")]
72 Month,
74 #[serde(rename = "1w")]
75 Week,
77 #[serde(rename = "1d")]
78 Day,
80 #[serde(rename = "1h")]
81 Hour,
83 #[serde(rename = "1m")]
84 Minute,
86 #[serde(rename = "1s")]
87 Second,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase")]
93pub enum TimeHistogramInterval {
95 CalendarInterval(CalendarInterval),
97 FixedInterval(String),
99}
100
101#[skip_serializing_none]
102#[derive(Debug, Clone, Serialize, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct TimeHistogramAggregate {
108 pub property: Vec<String>,
110 #[serde(flatten)]
111 pub interval: TimeHistogramInterval,
113 pub hard_bounds: Option<Bounds<String>>,
118 pub aggregates: Option<HashMap<String, RecordsAggregate>>,
120}
121
122#[derive(Serialize, Deserialize, Clone, Debug)]
123
124pub enum MovingFunction {
126 #[serde(rename = "MovingFunctions.max")]
127 Max,
129 #[serde(rename = "MovingFunctions.min")]
130 Min,
132 #[serde(rename = "MovingFunctions.sum")]
133 Sum,
135 #[serde(rename = "MovingFunctions.unweightedAvg")]
136 UnweightedAvg,
138 #[serde(rename = "MovingFunctions.linearWeightedAvg")]
139 LinearWeightedAvg,
141 #[serde(untagged)]
143 Other(String),
144}
145
146#[skip_serializing_none]
147#[derive(Debug, Clone, Serialize, Deserialize)]
148#[serde(rename_all = "camelCase")]
149pub struct MovingFunctionAggregate {
157 pub buckets_path: String,
161 pub window: u32,
163 pub function: MovingFunction,
165}
166
167#[skip_serializing_none]
168#[derive(Debug, Clone, Default, Serialize, Deserialize)]
169#[serde(rename_all = "camelCase")]
170pub struct FilterAggregate {
176 pub filters: Vec<AdvancedFilter>,
178 pub aggregates: Option<HashMap<String, RecordsAggregate>>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183#[serde(rename_all = "camelCase")]
184pub enum RecordsAggregate {
186 Avg(SimpleAggregate),
188 Count(SimpleAggregate),
190 Min(SimpleAggregate),
192 Max(SimpleAggregate),
194 Sum(SimpleAggregate),
196 UniqueValues(UniqueValuesAggregate),
198 NumberHistogram(NumberHistogramAggregate),
200 TimeHistogram(TimeHistogramAggregate),
202 MovingFunction(MovingFunctionAggregate),
204 Filters(FilterAggregate),
206}
207
208impl RecordsAggregate {
209 pub fn average(property: impl PropertyIdentifier) -> Self {
211 RecordsAggregate::Avg(SimpleAggregate {
212 property: property.into_identifier(),
213 })
214 }
215
216 pub fn count(property: impl PropertyIdentifier) -> Self {
218 RecordsAggregate::Count(SimpleAggregate {
219 property: property.into_identifier(),
220 })
221 }
222
223 pub fn min(property: impl PropertyIdentifier) -> Self {
225 RecordsAggregate::Min(SimpleAggregate {
226 property: property.into_identifier(),
227 })
228 }
229
230 pub fn max(property: impl PropertyIdentifier) -> Self {
232 RecordsAggregate::Max(SimpleAggregate {
233 property: property.into_identifier(),
234 })
235 }
236
237 pub fn sum(property: impl PropertyIdentifier) -> Self {
239 RecordsAggregate::Sum(SimpleAggregate {
240 property: property.into_identifier(),
241 })
242 }
243
244 pub fn unique_values(
249 property: impl PropertyIdentifier,
250 size: Option<u32>,
251 aggregates: Option<HashMap<String, RecordsAggregate>>,
252 ) -> Self {
253 RecordsAggregate::UniqueValues(UniqueValuesAggregate {
254 property: property.into_identifier(),
255 size,
256 aggregates,
257 })
258 }
259
260 pub fn number_histogram(
266 property: impl PropertyIdentifier,
267 interval: f64,
268 hard_bounds: Option<Bounds<f64>>,
269 aggregates: Option<HashMap<String, RecordsAggregate>>,
270 ) -> Self {
271 RecordsAggregate::NumberHistogram(NumberHistogramAggregate {
272 property: property.into_identifier(),
273 hard_bounds,
274 interval,
275 aggregates,
276 })
277 }
278
279 pub fn time_histogram(
285 property: impl PropertyIdentifier,
286 interval: TimeHistogramInterval,
287 hard_bounds: Option<Bounds<String>>,
288 aggregates: Option<HashMap<String, RecordsAggregate>>,
289 ) -> Self {
290 RecordsAggregate::TimeHistogram(TimeHistogramAggregate {
291 property: property.into_identifier(),
292 interval,
293 hard_bounds,
294 aggregates,
295 })
296 }
297
298 pub fn moving_function(
304 buckets_path: impl Into<String>,
305 window: u32,
306 function: MovingFunction,
307 ) -> Self {
308 RecordsAggregate::MovingFunction(MovingFunctionAggregate {
309 buckets_path: buckets_path.into(),
310 window,
311 function,
312 })
313 }
314
315 pub fn filters(
320 filters: Vec<AdvancedFilter>,
321 aggregates: Option<HashMap<String, RecordsAggregate>>,
322 ) -> Self {
323 RecordsAggregate::Filters(FilterAggregate {
324 filters,
325 aggregates,
326 })
327 }
328}
329
330#[skip_serializing_none]
332#[derive(Debug, Clone, Serialize, Deserialize)]
333#[serde(rename_all = "camelCase")]
334pub struct RecordsAggregateRequest {
335 pub last_updated_time: LastUpdatedTimeFilter,
339 pub filter: Option<AdvancedFilter>,
341 pub aggregates: HashMap<String, RecordsAggregate>,
343}
344
345#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
346#[serde(untagged)]
347pub enum AggregateValue {
349 String(String),
351 Integer(i64),
353 Number(f64),
355 Boolean(bool),
357}
358
359impl From<String> for AggregateValue {
360 fn from(value: String) -> Self {
361 AggregateValue::String(value)
362 }
363}
364
365impl<'a> From<&'a str> for AggregateValue {
366 fn from(value: &'a str) -> Self {
367 AggregateValue::String(value.to_string())
368 }
369}
370impl From<i64> for AggregateValue {
371 fn from(value: i64) -> Self {
372 AggregateValue::Integer(value)
373 }
374}
375impl From<f64> for AggregateValue {
376 fn from(value: f64) -> Self {
377 AggregateValue::Number(value)
378 }
379}
380impl From<bool> for AggregateValue {
381 fn from(value: bool) -> Self {
382 AggregateValue::Boolean(value)
383 }
384}
385
386#[skip_serializing_none]
387#[derive(Debug, Clone, Serialize, Deserialize)]
388#[serde(rename_all = "camelCase")]
389pub struct UniqueValuesBucket {
391 pub count: u64,
393 pub value: AggregateValue,
395 pub aggregates: Option<HashMap<String, AggregateResult>>,
397}
398
399#[skip_serializing_none]
400#[derive(Debug, Clone, Serialize, Deserialize)]
401#[serde(rename_all = "camelCase")]
402pub struct HistogramBucket<T> {
404 pub count: u64,
406 pub interval_start: T,
408 pub aggregates: Option<HashMap<String, AggregateResult>>,
410}
411
412#[skip_serializing_none]
413#[derive(Debug, Clone, Serialize, Deserialize)]
414#[serde(rename_all = "camelCase")]
415pub struct FilterBucket {
417 pub count: u64,
419 pub aggregates: Option<HashMap<String, AggregateResult>>,
421}
422
423#[derive(Debug, Clone, Serialize, Deserialize)]
424#[serde(untagged)]
425pub enum AggregateBuckets {
427 UniqueValues(Vec<UniqueValuesBucket>),
429 NumberHistogram(Vec<HistogramBucket<f64>>),
431 TimeHistogram(Vec<HistogramBucket<String>>),
433 Filter(Vec<FilterBucket>),
435}
436
437#[derive(Debug, Clone, Serialize, Deserialize)]
438#[serde(rename_all = "camelCase")]
439pub enum AggregateResult {
441 Avg(f64),
443 Count(u64),
445 Min(f64),
447 Max(f64),
449 Sum(f64),
451 Buckets(AggregateBuckets),
453 MovingFunction(f64),
455}
456
457#[derive(Debug, Clone, Serialize, Deserialize)]
458#[serde(rename_all = "camelCase")]
459pub struct RecordsAggregateResult {
461 pub aggregates: HashMap<String, AggregateResult>,
463}