Skip to main content

google_maps/distance_matrix/response/
mod.rs

1//! Resources (enums, structs) for processing the _Distance Matrix API_ response
2//! from the Google Maps Platform. Look in here for more information about the
3//! data returned from Google's server and how to parse it with your program.
4//! The Distance Matrix API shares many enums and struct with the _Directions
5//! API_. If you're not finding what you're looking for in this module, check
6//! out the Directions modules also.
7
8// -----------------------------------------------------------------------------
9
10pub mod element;
11pub mod element_status;
12pub mod row;
13pub mod status;
14
15// -----------------------------------------------------------------------------
16
17use crate::distance_matrix::{Error, response::{row::Row, status::Status}};
18use serde::{Deserialize, Serialize};
19
20// -----------------------------------------------------------------------------
21//
22/// Distance Matrix responses contain the following root elements.
23#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
24pub struct Response {
25    /// Contains an array of addresses as returned by the API from your original
26    /// request. As with `origin_addresses`, these are localized if appropriate.
27    #[serde(default)]
28    pub destination_addresses: Vec<String>,
29
30    /// When the status code is other than `OK`, there may be an additional
31    /// `error_message` field within the Directions response object. This field
32    /// contains more detailed information about the reasons behind the given
33    /// status code.
34    ///
35    /// **Note**: This field is not guaranteed to be always present, and its
36    /// content is subject to change.
37    pub error_message: Option<String>,
38
39    /// Contains an array of addresses as returned by the API from your original
40    /// request. These are formatted by the
41    /// [geocoder](https://developers.google.com/maps/documentation/geocoding/)
42    /// and localized according to the `language` parameter passed with the
43    /// request.
44    #[serde(default)]
45    pub origin_addresses: Vec<String>,
46
47    /// Contains an array of elements, which in turn each contain a `status`,
48    /// `duration`, and `distance` element.
49    #[serde(default)]
50    pub rows: Vec<Row>,
51
52    /// Contains metadata on the request.
53    pub status: Status,
54} // struct
55
56// -----------------------------------------------------------------------------
57
58impl std::convert::TryFrom<String> for Response {
59    type Error = serde_json::Error;
60    /// Convert a Google Maps API [JSON](https://en.wikipedia.org/wiki/JSON)
61    /// `String` response into a `Response` struct.
62    fn try_from(s: String) -> Result<Self, Self::Error> {
63        serde_json::from_slice(&s.into_bytes())
64    } // fn
65} // impl
66
67// -----------------------------------------------------------------------------
68
69impl std::str::FromStr for Response {
70    type Err = serde_json::Error;
71    /// Converts a Google Maps API [JSON](https://en.wikipedia.org/wiki/JSON)
72    /// `&str` response into a `Response` struct.
73    ///
74    /// # Notes
75    ///
76    /// * It's recommended to use the implemented `TryFrom` trait instead.
77    ///
78    /// * The [serde_json](https://crates.io/crates/simd-json)'s `from_str`
79    ///   function implementation is unsafe and it's `from_slice` function
80    ///   requires a mutable reference. Therefore this trait clones the `&str`
81    ///   into a `String` to give `from_slice` mutable access to the string.
82    fn from_str(s: &str) -> Result<Self, Self::Err> {
83        let bytes = s.to_string().into_bytes();
84        serde_json::from_slice(&bytes)
85    } // fn
86} // impl
87
88// -----------------------------------------------------------------------------
89
90impl std::convert::From<Response> for Result<Response, crate::distance_matrix::Error> {
91    /// Converts a Google Maps API `Response` into a `Result<Response, Error>`
92    /// by examining the `status` field inside of the response.
93    ///
94    /// If the status indicates a success, then an `Ok(response)` will be
95    /// returned. If the status indicates an error, then an `Err(error)` will be
96    /// returned.
97    fn from(response: Response) -> Self {
98        match response.status {
99            Status::Ok => Ok(response),
100            Status::InvalidRequest => Err(Error::InvalidRequest),
101            Status::MaxElementsExceeded => Err(Error::MaxElementsExceeded),
102            Status::MaxDimensionsExceeded => Err(Error::MaxDimensionsExceeded),
103            Status::OverDailyLimit => Err(Error::OverDailyLimit),
104            Status::OverQueryLimit => Err(Error::OverQueryLimit),
105            Status::RequestDenied => Err(Error::RequestDenied),
106            Status::UnknownError => Err(Error::UnknownError),
107        } // match
108    } // fn
109} // impl