1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::search::*;
use crate::util::*;
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(remote = "Self")]
pub struct GeoDistanceQuery {
#[serde(skip)]
field: String,
#[serde(skip)]
location: GeoLocation,
distance: Distance,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
distance_type: Option<GeoDistanceType>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
validation_method: Option<ValidationMethod>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
boost: Option<f32>,
#[serde(skip_serializing_if = "ShouldSkip::should_skip")]
_name: Option<String>,
}
impl Query {
pub fn geo_distance<T, U, V>(field: T, origin: U, distance: V) -> GeoDistanceQuery
where
T: ToString,
U: Into<GeoLocation>,
V: Into<Distance>,
{
GeoDistanceQuery {
field: field.to_string(),
location: origin.into(),
distance: distance.into(),
distance_type: None,
validation_method: None,
boost: None,
_name: None,
}
}
}
impl GeoDistanceQuery {
pub fn validation_method(mut self, validation_method: ValidationMethod) -> Self {
self.validation_method = Some(validation_method);
self
}
pub fn distance_type(mut self, distance_type: GeoDistanceType) -> Self {
self.distance_type = Some(distance_type);
self
}
add_boost_and_name!();
}
impl ShouldSkip for GeoDistanceQuery {}
serialize_with_root_key_value_pair!("geo_distance": GeoDistanceQuery, field, location);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serialization() {
assert_serialize_query(
Query::geo_distance(
"pin.location",
GeoLocation::new(40.12, -71.34),
Distance::Kilometers(300),
),
json!({
"geo_distance": {
"distance": "300km",
"pin.location": [-71.34, 40.12],
}
}),
);
assert_serialize_query(
Query::geo_distance(
"pin.location",
GeoLocation::new(40.12, -71.34),
Distance::Kilometers(300),
)
.distance_type(GeoDistanceType::Plane)
.validation_method(ValidationMethod::Strict)
.name("test_name")
.boost(1),
json!({
"geo_distance": {
"distance": "300km",
"distance_type": "plane",
"pin.location": [-71.34, 40.12],
"validation_method": "STRICT",
"_name": "test_name",
"boost": 1.0,
}
}),
);
}
}