google_maps/traits/query_url.rs
1// -----------------------------------------------------------------------------
2//
3/// Provides a way of converting a request `struct` (such as
4/// `crate::directions::Request` or `crate::elevation::Request`) to a
5/// [URL](https://en.wikipedia.org/wiki/Uniform_Resource_Locator) that
6/// can be used as an [HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP)
7/// [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET) request.
8pub trait QueryUrl {
9 /// Converts a request `struct` (presumably a request type such as
10 /// `crate::directions::Request`) to a
11 /// [URL](https://en.wikipedia.org/wiki/Uniform_Resource_Locator) that
12 /// can be used as an [HTTP](https://developer.mozilla.org/en-US/docs/Web/HTTP)
13 /// [GET](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET)
14 /// request.
15 ///
16 /// # Errors
17 ///
18 /// * This can fail if the request `struct` fails validation. For example,
19 /// parameters in the request conflict with one another, or the request
20 /// parameters are set in a way that's incompatible.
21 ///
22 /// For example, Google Maps Directions API cannot calculate alternative
23 /// routes if waypoints have been set. This will cause a validation
24 /// failure.
25 fn query_url(&self) -> Result<String, crate::Error>;
26} // trait QueryUrl
27
28// -----------------------------------------------------------------------------
29
30impl<T> QueryUrl for T
31where
32 T: crate::traits::Validatable + crate::traits::QueryString + crate::traits::EndPoint,
33{
34 /// Returns the URL query string that represents the request you've built.
35 ///
36 /// ## Description
37 ///
38 /// Returns the URL that will be used as the query to the Google Maps API.
39 ///
40 /// It is the result of the request builder pattern.
41 ///
42 /// This method can also be useful for records or logging. It can also be
43 /// used for passing to your HTTP client of choice and executing the HTTP
44 /// `GET` request yourself.
45 ///
46 /// ## Arguments
47 ///
48 /// This method accepts no arguments.
49 ///
50 /// # Errors
51 ///
52 /// * This can fail if the request `struct` fails validation. For example,
53 /// parameters in the request conflict with one another, or the request
54 /// parameters are set in a way that's incompatible.
55 ///
56 /// For example, Google Maps Directions API cannot calculate alternative
57 /// routes if waypoints have been set. This will cause a validation
58 /// failure.
59 fn query_url(&self) -> Result<String, crate::Error> {
60 // Validate the request before attempting to build a URL query string:
61 self.validate()?;
62
63 // If the request passes validation, build the full URL that will be
64 // used as the query:
65 #[allow(clippy::option_if_let_else)] // map_or_else is illegible
66 if let Some(output_format) = T::output_format() {
67 // An output format (i.e. `JSON` or `XML`) was defined for the
68 // end-point. Render it in the query URL:
69 Ok(format!(
70 "{service_url}/{output_format}?{query_string}",
71 service_url = T::service_url(),
72 query_string = self.query_string()
73 ))
74 } else {
75 // No output format was defined for the end-point. Don't render it
76 // in the query URL:
77 Ok(format!(
78 "{service_url}?{query_string}",
79 service_url = T::service_url(),
80 query_string = self.query_string()
81 ))
82 } // if
83 } // fn
84} // impl