vector/api/schema/
sort.rs1use std::cmp::Ordering;
2
3use async_graphql::{Enum, InputObject, InputType};
4use itertools::{
5 FoldWhile::{Continue, Done},
6 Itertools,
7};
8
9use crate::api::schema::{
10 components::{
11 sink::SinksSortFieldName, source::SourcesSortFieldName, transform::TransformsSortFieldName,
12 ComponentsSortFieldName,
13 },
14 metrics::source::file::FileSourceMetricFilesSortFieldName,
15};
16
17#[derive(Enum, Copy, Clone, Default, PartialEq, Eq)]
18pub enum Direction {
19 #[default]
20 Asc,
21 Desc,
22}
23
24#[derive(InputObject)]
25#[graphql(concrete(name = "ComponentsSortField", params(ComponentsSortFieldName)))]
26#[graphql(concrete(name = "SourcesSortField", params(SourcesSortFieldName)))]
27#[graphql(concrete(name = "TransformsSortField", params(TransformsSortFieldName)))]
28#[graphql(concrete(name = "SinksSortField", params(SinksSortFieldName)))]
29#[graphql(concrete(
30 name = "FileSourceMetricFilesSortField",
31 params(FileSourceMetricFilesSortFieldName)
32))]
33pub struct SortField<T: InputType> {
34 pub field: T,
35 #[graphql(default_with = "Direction::default()")]
36 pub direction: Direction,
37}
38
39pub trait SortableByField<T: InputType> {
41 fn sort(&self, rhs: &Self, field: &T) -> Ordering;
42}
43
44pub fn by_fields<T: InputType>(f: &mut [impl SortableByField<T>], sort_fields: &[SortField<T>]) {
46 f.sort_by(|a, b| {
47 sort_fields
48 .iter()
49 .fold_while(Ordering::Equal, |cmp, f| match cmp {
50 Ordering::Equal => {
51 let cmp = a.sort(b, &f.field);
52 Continue(match f.direction {
53 Direction::Desc => cmp.reverse(),
54 _ => cmp,
55 })
56 }
57 _ => Done(cmp),
58 })
59 .into_inner()
60 });
61}