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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
// -----------------------------------------------------------------------------
impl crate::traits::QueryString for crate::distance_matrix::Request<'_> {
/// Builds the URL [query string](https://en.wikipedia.org/wiki/Query_string)
/// for the HTTP [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET)
/// request. The query string is generated from the data found in this
/// `Request` structure.
///
/// ## Arguments
///
/// This method accepts no arguments.
///
/// ## Notes
///
/// * This function does not validate the request before generating the
/// _query string_. However, the superior method that generates the _query
/// URL_ does perform validation.
///
/// * The query string is the part of the URL after the `?` question mark.
/// For example, in the URL `https://example.com/over/there?name=ferret`
/// the query string is `name=ferret`
///
/// * There's no benefit to working on an owned `Request` struct (i.e. an
/// owned `self` versus an borrowed `&self`).
/// [percent-encoding](https://crates.io/crates/percent-encoding)
/// works on borrowed UTF-8 strings. Other types, such as enums and
/// numeric values are converted into strings. Therefore no zero-copy
/// operations are possible with an owned `self`.
fn query_string(&self) -> String {
// Builds the "required parameters" portion of the query string:
let mut query = format!(
"key={}&origins={}&destinations={}",
// Key:
self.client.key,
// Origins:
utf8_percent_encode(
&self
.origins
.iter()
.map(String::from)
.collect::<Vec<String>>()
.join("|"),
NON_ALPHANUMERIC
),
// Destinations:
utf8_percent_encode(
&self
.destinations
.iter()
.map(String::from)
.collect::<Vec<String>>()
.join("|"),
NON_ALPHANUMERIC
),
); // format!
// Builds the "optional parameters" portion of the query string:
// Arrival time key/value pair:
if let Some(arrival_time) = &self.arrival_time {
query.push_str("&arrival_time=");
query.push_str(&arrival_time.and_utc().timestamp().to_string());
} // if
// Avoid key/value pair:
if !self.restrictions.is_empty() {
query.push_str("&avoid=");
query.push_str(
&utf8_percent_encode(
&self
.restrictions
.iter()
.map(String::from)
.collect::<Vec<String>>()
.join("|"),
NON_ALPHANUMERIC,
)
.to_string(),
); // push_str
} // if
// Departure time key/value pair:
if let Some(departure_time) = &self.departure_time {
query.push_str("&departure_time=");
query.push_str(&String::from(departure_time));
} // if
// Language key/value pair:
if let Some(language) = &self.language {
query.push_str("&language=");
query.push_str(&String::from(language));
} // if
// Travel mode key/value pair:
if let Some(travel_mode) = &self.travel_mode {
query.push_str("&mode=");
query.push_str(&String::from(travel_mode).to_lowercase());
} // if
// Region key/value pair:
if let Some(region) = &self.region {
query.push_str("®ion=");
query.push_str(&String::from(region));
} // if
// Traffic model key/value pair:
if let Some(traffic_model) = &self.traffic_model {
query.push_str("&traffic_model=");
query.push_str(&String::from(traffic_model));
} // if
// Transit mode key/value pair:
if !self.transit_modes.is_empty() {
query.push_str("&transit_mode=");
query.push_str(
&utf8_percent_encode(
&self
.transit_modes
.iter()
.map(String::from)
.collect::<Vec<String>>()
.join("|"),
NON_ALPHANUMERIC,
)
.to_string(),
); // push_str
} // if
// Transit route preference key/value pair:
if let Some(transit_route_preference) = &self.transit_route_preference {
query.push_str("&transit_routing_preference=");
query.push_str(&String::from(transit_route_preference));
} // if
// Unit system key/value pair:
if let Some(unit_system) = &self.unit_system {
query.push_str("&units=");
query.push_str(&String::from(unit_system));
} // if
// Return built query string to caller:
query
} // fn
} // impl