opensearch_dsl/search/sort/
field_sort.rs1use serde::{Deserialize, Deserializer, Serialize};
2
3use super::{SortMode, SortOrder};
4use crate::{util::ShouldSkip, Term};
5
6#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
10#[serde(remote = "Self")]
11pub struct FieldSort {
12 #[serde(skip)]
13 field: String,
14
15 #[serde(default, skip_serializing_if = "ShouldSkip::should_skip")]
16 order: Option<SortOrder>,
17
18 #[serde(default, skip_serializing_if = "ShouldSkip::should_skip")]
19 mode: Option<SortMode>,
20
21 #[serde(default, skip_serializing_if = "ShouldSkip::should_skip")]
22 unmapped_type: Option<String>,
23
24 #[serde(default, skip_serializing_if = "ShouldSkip::should_skip")]
25 format: Option<String>,
26
27 #[serde(default, skip_serializing_if = "ShouldSkip::should_skip")]
28 missing: Option<Term>,
29}
30
31impl FieldSort {
32 pub fn new<T>(field: T) -> Self
34 where
35 T: ToString,
36 {
37 Self {
38 field: field.to_string(),
39 order: None,
40 mode: None,
41 unmapped_type: None,
42 format: None,
43 missing: None,
44 }
45 }
46
47 pub fn ascending<T>(field: T) -> Self
49 where
50 T: ToString,
51 {
52 Self::new(field).order(SortOrder::Asc)
53 }
54
55 pub fn descending<T>(field: T) -> Self
57 where
58 T: ToString,
59 {
60 Self::new(field).order(SortOrder::Desc)
61 }
62
63 pub fn order(mut self, order: SortOrder) -> Self {
67 self.order = Some(order);
68 self
69 }
70
71 pub fn mode(mut self, mode: SortMode) -> Self {
75 self.mode = Some(mode);
76 self
77 }
78
79 pub fn unmapped_type<T>(mut self, unmapped_type: T) -> Self
83 where
84 T: ToString,
85 {
86 self.unmapped_type = Some(unmapped_type.to_string());
87 self
88 }
89
90 pub fn format<T>(mut self, format: T) -> Self
94 where
95 T: ToString,
96 {
97 self.format = Some(format.to_string());
98 self
99 }
100
101 pub fn missing<T>(mut self, missing: T) -> Self
106 where
107 T: Serialize,
108 {
109 self.missing = Term::new(missing);
110 self
111 }
112}
113
114impl IntoIterator for FieldSort {
115 type IntoIter = std::option::IntoIter<Self::Item>;
116 type Item = Self;
117
118 fn into_iter(self) -> Self::IntoIter {
119 Some(self).into_iter()
120 }
121}
122
123serialize_keyed!(FieldSort: field);
124impl<'de> Deserialize<'de> for FieldSort {
125 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
126 where
127 D: Deserializer<'de>,
128 {
129 use std::fmt;
130 struct WrapperVisitor;
131
132 impl<'de> serde::de::Visitor<'de> for WrapperVisitor {
133 type Value = FieldSort;
134
135 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
136 formatter.write_str("struct fieldsort")
137 }
138
139 fn visit_map<A>(self, mut map: A) -> Result<FieldSort, A::Error>
140 where
141 A: serde::de::MapAccess<'de>,
142 {
143 let mut sorter: FieldSort = FieldSort::default();
144
145 while let Some(key) = map.next_key::<String>()? {
146 let inner_map =
147 map.next_value::<serde_json::Map<String, serde_json::Value>>()?;
148 sorter.field = key.to_owned();
149 for (k, v) in inner_map.iter() {
150 match k.as_str() {
151 "unmapped_type" => match v.as_str() {
152 Some(value) => {
153 sorter.unmapped_type = Some(value.to_string());
154 }
155 None => {
156 return Err(serde::de::Error::invalid_type(
157 serde::de::Unexpected::Other("not a string"),
158 &"a string",
159 ));
160 }
161 },
162 "format" => match v.as_str() {
163 Some(value) => {
164 sorter.format = Some(value.to_string());
165 }
166 None => {
167 return Err(serde::de::Error::invalid_type(
168 serde::de::Unexpected::Other("not a string"),
169 &"a string",
170 ));
171 }
172 },
173 "order" => {
174 let value = serde_json::from_value::<SortOrder>(v.clone());
175 match value {
176 Ok(value) => {
177 sorter.order = Some(value);
178 }
179 Err(e) => {
180 return Err(serde::de::Error::custom(format!(
181 "error parsing {}: {}",
182 k, e
183 )));
184 }
185 }
186 }
187 "mode" => {
188 let value = serde_json::from_value::<SortMode>(v.clone());
189 match value {
190 Ok(value) => {
191 sorter.mode = Some(value);
192 }
193 Err(e) => {
194 return Err(serde::de::Error::custom(format!(
195 "error parsing {}: {}",
196 k, e
197 )));
198 }
199 }
200 }
201 "missing" => {
202 let value = serde_json::from_value::<Term>(v.clone());
203 match value {
204 Ok(value) => {
205 sorter.missing = Some(value);
206 }
207 Err(e) => {
208 return Err(serde::de::Error::custom(format!(
209 "error parsing {}: {}",
210 k, e
211 )));
212 }
213 }
214 }
215 _ => {
216 return Err(serde::de::Error::custom(format!(
217 "fielderror: error parsing {}",
218 k
219 )));
220 }
221 }
222 }
223 }
224 if !sorter.field.is_empty() {
225 Ok(sorter)
226 } else {
227 Err(serde::de::Error::missing_field("required field"))
228 }
229 }
230 }
231
232 deserializer.deserialize_map(WrapperVisitor)
233 }
234}
235
236#[cfg(test)]
237mod tests {
238 use super::*;
239 use crate::{util::assert_serialize, SortSpecialField};
240
241 #[test]
242 fn serialization() {
243 assert_serialize(FieldSort::new("test"), json!({"test": {}}));
244
245 assert_serialize(
246 FieldSort::new(SortSpecialField::Score),
247 json!({"_score": {}}),
248 );
249
250 assert_serialize(
251 FieldSort::ascending("field"),
252 json!({ "field": { "order": "asc" } }),
253 );
254
255 assert_serialize(
256 FieldSort::descending("field"),
257 json!({ "field": { "order": "desc" } }),
258 );
259
260 assert_serialize(
261 FieldSort::ascending("test")
262 .order(SortOrder::Asc)
263 .mode(SortMode::Max)
264 .unmapped_type("long")
265 .missing("miss"),
266 json!({
267 "test": {
268 "order": "asc",
269 "mode": "max",
270 "unmapped_type": "long",
271 "missing": "miss",
272 }
273 }),
274 );
275 }
276}