elasticsearch_dsl/search/sort/
sort_collection.rs

1use super::{FieldSort, Sort};
2use crate::util::ShouldSkip;
3
4/// A sorting criteria
5#[derive(Default, Clone, PartialEq, Serialize)]
6pub struct SortCollection(Vec<Sort>);
7
8impl std::fmt::Debug for SortCollection {
9    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10        self.0.fmt(f)
11    }
12}
13
14impl IntoIterator for SortCollection {
15    type Item = Sort;
16
17    type IntoIter = std::vec::IntoIter<Self::Item>;
18
19    fn into_iter(self) -> Self::IntoIter {
20        self.0.into_iter()
21    }
22}
23
24impl ShouldSkip for SortCollection {
25    fn should_skip(&self) -> bool {
26        self.0.should_skip()
27    }
28}
29
30impl SortCollection {
31    /// Creates a new instance of [SortCollection]
32    pub fn new() -> Self {
33        Default::default()
34    }
35
36    /// Extends sorting collection
37    pub fn extend<T>(&mut self, sort: T)
38    where
39        T: IntoIterator,
40        T::Item: Into<Sort>,
41    {
42        self.0.extend(sort.into_iter().map(Into::into))
43    }
44
45    /// Add a field to sort by ascending order
46    pub fn ascending<T>(mut self, field: T) -> Self
47    where
48        T: ToString,
49    {
50        self.0.push(Sort::FieldSort(FieldSort::ascending(field)));
51        self
52    }
53
54    /// Add a field to sort by descending order
55    pub fn descending<T>(mut self, field: T) -> Self
56    where
57        T: ToString,
58    {
59        self.0.push(Sort::FieldSort(FieldSort::descending(field)));
60        self
61    }
62
63    /// Add a field sort
64    pub fn field(mut self, field_sort: FieldSort) -> Self {
65        self.0.push(Sort::FieldSort(field_sort));
66        self
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use crate::util::assert_serialize_sort;
74    use crate::SortSpecialField;
75
76    #[test]
77    fn serializes_correctly() {
78        assert_serialize_sort(["abc", "def"], json!(["abc", "def"]));
79
80        assert_serialize_sort(
81            [
82                FieldSort::ascending("field1"),
83                FieldSort::descending("field2"),
84            ],
85            json!([
86                { "field1": { "order": "asc" } },
87                { "field2": { "order": "desc" } },
88            ]),
89        );
90
91        assert_serialize_sort(
92            [
93                Sort::FieldSort(
94                    FieldSort::ascending("post_date").format("strict_date_optional_time_nanos"),
95                ),
96                Sort::Field("user".to_string()),
97                Sort::FieldSort(FieldSort::descending("name")),
98                Sort::FieldSort(FieldSort::descending("age")),
99                Sort::SpecialField(SortSpecialField::Score),
100            ],
101            json!([
102                { "post_date" : {"order" : "asc", "format": "strict_date_optional_time_nanos" } },
103                "user",
104                { "name" : { "order": "desc" } },
105                { "age" : { "order": "desc" } },
106                "_score"
107            ]),
108        );
109
110        assert_serialize_sort(
111            SortCollection::new()
112                .ascending("name")
113                .descending("age")
114                .field(FieldSort::ascending("post_date").format("strict_date_optional_time_nanos")),
115            json!([
116                { "name" : { "order": "asc" } },
117                { "age" : { "order": "desc" } },
118                { "post_date" : {"order" : "asc", "format": "strict_date_optional_time_nanos" } },
119            ]),
120        );
121    }
122}