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