1use serde::{Deserialize, Serialize};
2
3#[derive(Default, Debug, Serialize, Deserialize, Clone)]
5#[serde(rename_all = "camelCase")]
6pub struct CohortSpec {
7 #[serde(skip_serializing_if = "Option::is_none")]
8 pub cohorts: Option<Vec<Cohort>>,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub cohorts_range: Option<CohortsRange>,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub cohort_report_settings: Option<CohortReportSettings>,
13}
14
15#[derive(Default, Debug, Serialize, Deserialize, Clone)]
16#[serde(rename_all = "camelCase")]
17pub struct Cohort {
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub name: Option<String>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub dimension: Option<String>,
22 #[serde(skip_serializing_if = "Option::is_none")]
23 pub date_range: Option<DateRange>,
24}
25
26#[derive(Default, Debug, Serialize, Deserialize, Clone)]
27#[serde(rename_all = "camelCase")]
28pub struct CohortsRange {
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub granularity: Option<Granularity>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub start_offset: Option<i32>,
33 #[serde(skip_serializing_if = "Option::is_none")]
34 pub end_offset: Option<i32>,
35}
36
37#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
39#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
40pub enum Granularity {
41 GranularityUnspecified,
42 Daily,
43 Weekly,
44 Monthly,
45}
46
47#[derive(Default, Debug, Serialize, Deserialize, Clone)]
48#[serde(rename_all = "camelCase")]
49pub struct CohortReportSettings {
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub accumulate: Option<bool>,
52}
53
54#[derive(Default, Debug, Serialize, Deserialize, Clone)]
56#[serde(rename_all = "camelCase")]
57pub struct DateRange {
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub start_date: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub end_date: Option<String>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub name: Option<String>,
64}
65
66impl DateRange {
67 pub fn new(name: &str, start: &str, end: &str) -> DateRange {
68 DateRange {
69 name: Some(name.to_string()),
70 start_date: Some(start.to_string()),
71 end_date: Some(end.to_string()),
72 }
73 }
74}
75
76#[derive(Default, Debug, Serialize, Deserialize, Clone)]
78#[serde(rename_all = "camelCase")]
79pub struct Dimension {
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub name: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub dimension_expression: Option<DimensionExpression>,
84}
85
86impl Dimension {
87 pub fn new(name: &str) -> Dimension {
88 Dimension {
89 name: Some(name.to_string()),
90 ..Dimension::default()
91 }
92 }
93 pub fn from_string_vec(vals: Vec<&str>) -> Vec<Self> {
94 vals.into_iter().map(Self::new).collect()
95 }
96}
97
98#[derive(Default, Debug, Serialize, Deserialize, Clone)]
99#[serde(rename_all = "camelCase")]
100pub struct DimensionExpression {
101 #[serde(skip_serializing_if = "Option::is_none")]
102 pub lower_case: Option<CaseExpression>,
103 #[serde(skip_serializing_if = "Option::is_none")]
104 pub upper_case: Option<CaseExpression>,
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub concatenate: Option<ConcatenateExpression>,
107}
108
109#[derive(Default, Debug, Serialize, Deserialize, Clone)]
110#[serde(rename_all = "camelCase")]
111pub struct CaseExpression {
112 #[serde(skip_serializing_if = "Option::is_none")]
113 pub dimension_name: Option<String>,
114}
115
116#[derive(Default, Debug, Serialize, Deserialize, Clone)]
117#[serde(rename_all = "camelCase")]
118pub struct ConcatenateExpression {
119 #[serde(skip_serializing_if = "Option::is_none")]
120 pub dimension_names: Option<Vec<String>>,
121 #[serde(skip_serializing_if = "Option::is_none")]
122 pub delimiter: Option<String>,
123}
124
125#[derive(Default, Debug, Serialize, Deserialize, Clone)]
127#[serde(rename_all = "camelCase")]
128pub struct DimensionHeader {
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub name: Option<String>,
131}
132
133#[derive(Default, Debug, Serialize, Deserialize, Clone)]
135#[serde(rename_all = "camelCase")]
136pub struct DimensionMetadata {
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub api_name: Option<String>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub ui_name: Option<String>,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub description: Option<String>,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub deprecated_api_names: Option<Vec<String>>,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub custom_definition: Option<bool>,
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub category: Option<String>,
149}
150
151#[derive(Default, Debug, Serialize, Deserialize, Clone)]
153#[serde(rename_all = "camelCase")]
154pub struct DimensionValue {
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub value: Option<String>,
157}
158
159#[derive(Default, Debug, Serialize, Deserialize, Clone)]
161#[serde(rename_all = "camelCase")]
162pub struct FilterExpression {
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub and_group: Option<FilterExpressionList>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub or_group: Option<FilterExpressionList>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 pub not_expression: Option<Box<FilterExpression>>,
169 #[serde(skip_serializing_if = "Option::is_none")]
170 pub filter: Option<Filter>,
171}
172
173#[derive(Default, Debug, Serialize, Deserialize, Clone)]
174#[serde(rename_all = "camelCase")]
175pub struct FilterExpressionList {
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub expressions: Option<Vec<FilterExpression>>,
178}
179
180#[derive(Default, Debug, Serialize, Deserialize, Clone)]
181#[serde(rename_all = "camelCase")]
182pub struct Filter {
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub field_name: Option<String>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub string_filter: Option<StringFilter>,
187 #[serde(skip_serializing_if = "Option::is_none")]
188 pub in_list_filter: Option<InListFilter>,
189 #[serde(skip_serializing_if = "Option::is_none")]
190 pub numeric_filter: Option<NumericFilter>,
191 #[serde(skip_serializing_if = "Option::is_none")]
192 pub between_filter: Option<BetweenFilter>,
193}
194
195#[derive(Default, Debug, Serialize, Deserialize, Clone)]
196#[serde(rename_all = "camelCase")]
197pub struct StringFilter {
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub match_type: Option<MatchType>,
200 #[serde(skip_serializing_if = "Option::is_none")]
201 pub value: Option<String>,
202 #[serde(skip_serializing_if = "Option::is_none")]
203 pub case_sensitive: Option<bool>,
204}
205
206#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
207#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
208pub enum MatchType {
209 MatchTypeUnspecified,
210 Exact,
211 BeginsWith,
212 EndsWith,
213 Contains,
214 FullRegexp,
215 PartialRegexp,
216}
217
218#[derive(Default, Debug, Serialize, Deserialize, Clone)]
219#[serde(rename_all = "camelCase")]
220pub struct InListFilter {
221 #[serde(skip_serializing_if = "Option::is_none")]
222 pub values: Option<Vec<String>>,
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub case_sensitive: Option<bool>,
225}
226
227#[derive(Default, Debug, Serialize, Deserialize, Clone)]
228#[serde(rename_all = "camelCase")]
229pub struct NumericFilter {
230 #[serde(skip_serializing_if = "Option::is_none")]
231 pub operation: Option<Operation>,
232 #[serde(skip_serializing_if = "Option::is_none")]
233 pub value: Option<NumericValue>,
234}
235
236#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
237#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
238pub enum Operation {
239 OperationUnspecified,
240 Equal,
241 LessThan,
242 LessThanOrEqual,
243 GreaterThan,
244 GreaterThanOrEqual,
245}
246
247#[derive(Default, Debug, Serialize, Deserialize, Clone)]
248#[serde(rename_all = "camelCase")]
249pub struct NumericValue {
250 #[serde(rename = "int64Value", skip_serializing_if = "Option::is_none")]
251 pub int64_value: Option<String>,
252 #[serde(skip_serializing_if = "Option::is_none")]
253 pub double_value: Option<f64>,
254}
255
256#[derive(Default, Debug, Serialize, Deserialize, Clone)]
257#[serde(rename_all = "camelCase")]
258pub struct BetweenFilter {
259 #[serde(skip_serializing_if = "Option::is_none")]
260 pub from_value: Option<NumericValue>,
261 #[serde(skip_serializing_if = "Option::is_none")]
262 pub to_value: Option<NumericValue>,
263}
264
265#[derive(Default, Debug, Serialize, Deserialize, Clone)]
267#[serde(rename_all = "camelCase")]
268pub struct Metric {
269 #[serde(skip_serializing_if = "Option::is_none")]
270 pub name: Option<String>,
271 #[serde(skip_serializing_if = "Option::is_none")]
272 pub expression: Option<String>,
273 #[serde(skip_serializing_if = "Option::is_none")]
274 pub invisible: Option<bool>,
275}
276
277impl Metric {
278 pub fn new(name: &str) -> Metric {
279 Metric {
280 name: Some(name.to_string()),
281 ..Metric::default()
282 }
283 }
284 pub fn from_string_vec(vals: Vec<&str>) -> Vec<Self> {
285 vals.into_iter().map(Self::new).collect()
286 }
287}
288
289#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
291#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
292pub enum MetricAggregation {
293 MetricAggregationUnspecified,
294 Total,
295 Minimum,
296 Maximum,
297 Count,
298}
299
300#[derive(Default, Debug, Serialize, Deserialize, Clone)]
302#[serde(rename_all = "camelCase")]
303pub struct MetricHeader {
304 #[serde(skip_serializing_if = "Option::is_none")]
305 pub name: Option<String>,
306 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
307 pub metric_type: Option<String>,
308}
309
310#[derive(Default, Debug, Serialize, Deserialize, Clone)]
312#[serde(rename_all = "camelCase")]
313pub struct MetricMetadata {
314 #[serde(skip_serializing_if = "Option::is_none")]
315 pub api_name: Option<String>,
316 #[serde(skip_serializing_if = "Option::is_none")]
317 pub ui_name: Option<String>,
318 #[serde(skip_serializing_if = "Option::is_none")]
319 pub description: Option<String>,
320 #[serde(skip_serializing_if = "Option::is_none")]
321 pub deprecated_api_names: Option<Vec<String>>,
322 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
323 pub metric_type: Option<String>,
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub expression: Option<String>,
326 #[serde(skip_serializing_if = "Option::is_none")]
327 pub custom_definition: Option<bool>,
328 #[serde(skip_serializing_if = "Option::is_none")]
329 pub blocked_reasons: Option<Vec<String>>,
330 #[serde(skip_serializing_if = "Option::is_none")]
331 pub category: Option<String>,
332}
333
334#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
336#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
337pub enum MetricType {
338 MetricTypeUnspecified,
339 TypeInteger,
340 TypeFloat,
341 TypeSeconds,
342 TypeMilliseconds,
343 TypeMinutes,
344 TypeHours,
345 TypeStandard,
346 TypeCurrency,
347 TypeFeet,
348 TypeMiles,
349 TypeMeters,
350 TypeKilometers,
351}
352
353#[derive(Default, Debug, Serialize, Deserialize, Clone)]
355#[serde(rename_all = "camelCase")]
356pub struct OrderBy {
357 #[serde(skip_serializing_if = "Option::is_none")]
358 pub metric: Option<MetricOrderBy>,
359 #[serde(skip_serializing_if = "Option::is_none")]
360 pub dimension: Option<DimensionOrderBy>,
361 #[serde(skip_serializing_if = "Option::is_none")]
362 pub pivot: Option<PivotOrderBy>,
363 #[serde(skip_serializing_if = "Option::is_none")]
364 pub desc: Option<bool>,
365}
366
367impl OrderBy {
368 pub fn metric(metric_name: &str, desc: bool) -> OrderBy {
369 OrderBy {
370 metric: Some(MetricOrderBy {
371 metric_name: Some(metric_name.to_string()),
372 }),
373 desc: Some(desc),
374 ..OrderBy::default()
375 }
376 }
377 pub fn dimension(dimension_name: &str, desc: bool) -> OrderBy {
378 OrderBy {
379 dimension: Some(DimensionOrderBy {
380 dimension_name: Some(dimension_name.to_string()),
381 order_type: None,
382 }),
383 desc: Some(desc),
384 ..OrderBy::default()
385 }
386 }
387}
388
389#[derive(Default, Debug, Serialize, Deserialize, Clone)]
390#[serde(rename_all = "camelCase")]
391pub struct MetricOrderBy {
392 #[serde(skip_serializing_if = "Option::is_none")]
393 pub metric_name: Option<String>,
394}
395
396#[derive(Default, Debug, Serialize, Deserialize, Clone)]
397#[serde(rename_all = "camelCase")]
398pub struct DimensionOrderBy {
399 #[serde(skip_serializing_if = "Option::is_none")]
400 pub dimension_name: Option<String>,
401 #[serde(skip_serializing_if = "Option::is_none")]
402 pub order_type: Option<OrderType>,
403}
404
405#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
406#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
407pub enum OrderType {
408 OrderTypeUnspecified,
409 Alphanumeric,
410 CaseInsensitiveAlphanumeric,
411 Numeric,
412}
413
414#[derive(Default, Debug, Serialize, Deserialize, Clone)]
415#[serde(rename_all = "camelCase")]
416pub struct PivotOrderBy {
417 #[serde(skip_serializing_if = "Option::is_none")]
418 pub metric_name: Option<String>,
419 #[serde(skip_serializing_if = "Option::is_none")]
420 pub pivot_selections: Option<Vec<PivotSelection>>,
421}
422
423#[derive(Default, Debug, Serialize, Deserialize, Clone)]
424#[serde(rename_all = "camelCase")]
425pub struct PivotSelection {
426 #[serde(skip_serializing_if = "Option::is_none")]
427 pub dimension_name: Option<String>,
428 #[serde(skip_serializing_if = "Option::is_none")]
429 pub dimension_value: Option<String>,
430}
431
432#[derive(Default, Debug, Serialize, Deserialize, Clone)]
434#[serde(rename_all = "camelCase")]
435pub struct Pivot {
436 #[serde(skip_serializing_if = "Option::is_none")]
437 pub field_names: Option<Vec<String>>,
438 #[serde(skip_serializing_if = "Option::is_none")]
439 pub order_bys: Option<Vec<OrderBy>>,
440 #[serde(skip_serializing_if = "Option::is_none")]
441 pub offset: Option<String>,
442 #[serde(skip_serializing_if = "Option::is_none")]
443 pub limit: Option<String>,
444 #[serde(skip_serializing_if = "Option::is_none")]
445 pub metric_aggregations: Option<Vec<MetricAggregation>>,
446}
447
448#[derive(Default, Debug, Serialize, Deserialize, Clone)]
450#[serde(rename_all = "camelCase")]
451pub struct PropertyQuota {
452 #[serde(skip_serializing_if = "Option::is_none")]
453 pub tokens_per_day: Option<QuotaStatus>,
454 #[serde(skip_serializing_if = "Option::is_none")]
455 pub tokens_per_hour: Option<QuotaStatus>,
456 #[serde(skip_serializing_if = "Option::is_none")]
457 pub concurrent_requests: Option<QuotaStatus>,
458 #[serde(skip_serializing_if = "Option::is_none")]
459 pub server_errors_per_project_per_hour: Option<QuotaStatus>,
460 #[serde(skip_serializing_if = "Option::is_none")]
461 pub potentially_thresholded_requests_per_hour: Option<QuotaStatus>,
462}
463
464#[derive(Default, Debug, Serialize, Deserialize, Clone)]
465#[serde(rename_all = "camelCase")]
466pub struct QuotaStatus {
467 #[serde(skip_serializing_if = "Option::is_none")]
468 pub consumed: Option<i32>,
469 #[serde(skip_serializing_if = "Option::is_none")]
470 pub remaining: Option<i32>,
471}
472
473#[derive(Default, Debug, Serialize, Deserialize, Clone)]
475#[serde(rename_all = "camelCase")]
476pub struct ResponseMetaData {
477 #[serde(skip_serializing_if = "Option::is_none")]
478 pub data_loss_from_other_row: Option<bool>,
479 #[serde(skip_serializing_if = "Option::is_none")]
480 pub schema_restriction_response: Option<SchemaRestrictionResponse>,
481 #[serde(skip_serializing_if = "Option::is_none")]
482 pub currency_code: Option<String>,
483 #[serde(skip_serializing_if = "Option::is_none")]
484 pub time_zone: Option<String>,
485 #[serde(skip_serializing_if = "Option::is_none")]
486 pub empty_reason: Option<String>,
487 #[serde(skip_serializing_if = "Option::is_none")]
488 pub subject_to_thresholding: Option<bool>,
489}
490
491#[derive(Default, Debug, Serialize, Deserialize, Clone)]
492#[serde(rename_all = "camelCase")]
493pub struct SchemaRestrictionResponse {
494 #[serde(skip_serializing_if = "Option::is_none")]
495 pub active_metric_restrictions: Option<Vec<ActiveMetricRestriction>>,
496}
497
498#[derive(Default, Debug, Serialize, Deserialize, Clone)]
499#[serde(rename_all = "camelCase")]
500pub struct ActiveMetricRestriction {
501 #[serde(skip_serializing_if = "Option::is_none")]
502 pub restricted_metric_types: Option<Vec<RestrictedMetricType>>,
503 #[serde(skip_serializing_if = "Option::is_none")]
504 pub metric_name: Option<String>,
505}
506
507#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
508#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
509pub enum RestrictedMetricType {
510 RestrictedMetricTypeUnspecified,
511 CostData,
512 RevenueData,
513}
514
515#[derive(Default, Debug, Serialize, Deserialize, Clone)]
517#[serde(rename_all = "camelCase")]
518pub struct Row {
519 #[serde(skip_serializing_if = "Option::is_none")]
520 pub dimension_values: Option<Vec<DimensionValue>>,
521 #[serde(skip_serializing_if = "Option::is_none")]
522 pub metric_values: Option<Vec<MetricValue>>,
523}
524
525#[derive(Default, Debug, Serialize, Deserialize, Clone)]
526#[serde(rename_all = "camelCase")]
527pub struct MetricValue {
528 #[serde(skip_serializing_if = "Option::is_none")]
529 pub value: Option<String>,
530}
531
532#[derive(Default, Debug, Serialize, Deserialize, Clone)]
534#[serde(rename_all = "camelCase")]
535pub struct RunPivotReportResponse {
536 #[serde(skip_serializing_if = "Option::is_none")]
537 pub pivot_headers: Option<Vec<PivotHeader>>,
538 #[serde(skip_serializing_if = "Option::is_none")]
539 pub dimension_headers: Option<Vec<DimensionHeader>>,
540 #[serde(skip_serializing_if = "Option::is_none")]
541 pub metric_headers: Option<Vec<MetricHeader>>,
542 #[serde(skip_serializing_if = "Option::is_none")]
543 pub rows: Option<Vec<Row>>,
544 #[serde(skip_serializing_if = "Option::is_none")]
545 pub aggregates: Option<Vec<Row>>,
546 #[serde(skip_serializing_if = "Option::is_none")]
547 pub metadata: Option<ResponseMetaData>,
548 #[serde(skip_serializing_if = "Option::is_none")]
549 pub property_quota: Option<PropertyQuota>,
550 #[serde(skip_serializing_if = "Option::is_none")]
551 pub kind: Option<String>,
552}
553
554#[derive(Default, Debug, Serialize, Deserialize, Clone)]
555#[serde(rename_all = "camelCase")]
556pub struct PivotHeader {
557 #[serde(skip_serializing_if = "Option::is_none")]
558 pub pivot_dimension_headers: Option<Vec<PivotDimensionHeader>>,
559 #[serde(skip_serializing_if = "Option::is_none")]
560 pub row_count: Option<i32>,
561}
562
563#[derive(Default, Debug, Serialize, Deserialize, Clone)]
564#[serde(rename_all = "camelCase")]
565pub struct PivotDimensionHeader {
566 #[serde(skip_serializing_if = "Option::is_none")]
567 pub dimension_values: Option<Vec<DimensionValue>>,
568}
569
570#[derive(Default, Debug, Serialize, Deserialize, Clone)]
572#[serde(rename_all = "camelCase")]
573pub struct RunReportResponse {
574 #[serde(skip_serializing_if = "Option::is_none")]
575 pub dimension_headers: Option<Vec<DimensionHeader>>,
576 #[serde(skip_serializing_if = "Option::is_none")]
577 pub metric_headers: Option<Vec<MetricHeader>>,
578 #[serde(skip_serializing_if = "Option::is_none")]
579 pub rows: Option<Vec<Row>>,
580 #[serde(skip_serializing_if = "Option::is_none")]
581 pub totals: Option<Vec<Row>>,
582 #[serde(skip_serializing_if = "Option::is_none")]
583 pub maximums: Option<Vec<Row>>,
584 #[serde(skip_serializing_if = "Option::is_none")]
585 pub minimums: Option<Vec<Row>>,
586 #[serde(skip_serializing_if = "Option::is_none")]
587 pub row_count: Option<i32>,
588 #[serde(skip_serializing_if = "Option::is_none")]
589 pub metadata: Option<ResponseMetaData>,
590 #[serde(skip_serializing_if = "Option::is_none")]
591 pub property_quota: Option<PropertyQuota>,
592 #[serde(skip_serializing_if = "Option::is_none")]
593 pub kind: Option<String>,
594}