Skip to main content

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