Skip to main content

opensearch_dsl/search/sort/
sort_collection.rs

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