Add module src/free_api_v25/query/queryparams.rs
This commit is contained in:
parent
0c7839b92b
commit
96bd494161
@ -18,5 +18,10 @@
|
|||||||
//! assert!(url.contains("q=London"));
|
//! assert!(url.contains("q=London"));
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
pub mod queryparams;
|
||||||
pub mod units;
|
pub mod units;
|
||||||
pub mod urls;
|
pub mod urls;
|
||||||
|
|
||||||
|
pub use queryparams::*;
|
||||||
|
pub use units::*;
|
||||||
|
pub use urls::*;
|
||||||
|
126
src/free_api_v25/query/queryparams.rs
Normal file
126
src/free_api_v25/query/queryparams.rs
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
use super::{
|
||||||
|
Units,
|
||||||
|
urls::{FORECAST_URL, WEATHER_URL},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Query parameters for `OpenWeatherMap` API.
|
||||||
|
///
|
||||||
|
/// **Note:** One of `city_id`, `city_name`, `(lat, lon)` pair, or `zip` **must** be provided,
|
||||||
|
/// otherwise URL building will fail.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct QueryParams {
|
||||||
|
/// Your `OpenWeatherMap` API key
|
||||||
|
pub api_key: String,
|
||||||
|
|
||||||
|
/// City ID (optional)
|
||||||
|
///
|
||||||
|
/// You can make an API call by city ID to get an unambiguous result for your city.
|
||||||
|
/// The list of city IDs (`city.list.json.gz`) can be downloaded [here](http://bulk.openweathermap.org/sample/).
|
||||||
|
pub city_id: Option<String>,
|
||||||
|
|
||||||
|
/// City name (optional)
|
||||||
|
///
|
||||||
|
/// You can call by city name, or city name + state code + country code.
|
||||||
|
/// Searching by state is only available for locations in the USA.
|
||||||
|
/// See: <https://openweathermap.org/current#name>
|
||||||
|
pub city_name: Option<String>,
|
||||||
|
|
||||||
|
/// Latitude (optional, must be used with `lon`)
|
||||||
|
pub lat: Option<f32>,
|
||||||
|
|
||||||
|
/// Longitude (optional, must be used with `lat`)
|
||||||
|
pub lon: Option<f32>,
|
||||||
|
|
||||||
|
/// Zip code (optional)
|
||||||
|
///
|
||||||
|
/// Format: `"94040,us"`. If the country code is not specified, it defaults to USA.
|
||||||
|
pub zip: Option<String>,
|
||||||
|
|
||||||
|
/// Units for temperature and wind (default `"Standard"`)
|
||||||
|
pub units: Units,
|
||||||
|
|
||||||
|
/// Language code for descriptions (default `"en"`)
|
||||||
|
pub lang: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QueryParams {
|
||||||
|
/// Build query URL for the `/weather` endpoint.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an `Err` if no valid location is specified
|
||||||
|
/// (`city_id`, `city_name`, `lat`/`lon`, or `zip` are all None).
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use owm_api25::query::{QueryParams, Units, WEATHER_URL};
|
||||||
|
///
|
||||||
|
/// let query = QueryParams {
|
||||||
|
/// api_key: "MY_API_KEY".to_string(),
|
||||||
|
/// city_name: Some("London".to_string()),
|
||||||
|
/// ..Default::default()
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// let url = query.weather_url().unwrap();
|
||||||
|
/// assert!(url.contains("q=London"));
|
||||||
|
/// assert!(url.contains("appid=MY_API_KEY"));
|
||||||
|
/// ```
|
||||||
|
pub fn weather_url(&self) -> Result<String, String> {
|
||||||
|
self.build_url(WEATHER_URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build query URL for the `/forecast` endpoint.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an `Err` if no valid location is specified.
|
||||||
|
/// See `weather_url`.
|
||||||
|
pub fn forecast_url(&self) -> Result<String, String> {
|
||||||
|
self.build_url(FORECAST_URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Internal helper to build query URL.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an `Err` if no valid location is specified (`city_id`, `city_name`, `lat`/`lon`, or `zip`).
|
||||||
|
fn build_url(&self, base: &str) -> Result<String, String> {
|
||||||
|
let mut params = vec![
|
||||||
|
format!("appid={}", self.api_key),
|
||||||
|
format!("units={}", self.units),
|
||||||
|
format!("lang={}", self.lang),
|
||||||
|
"mode=json".to_string(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if let Some(ref id) = self.city_id {
|
||||||
|
params.push(format!("id={id}"));
|
||||||
|
} else if let Some(ref name) = self.city_name {
|
||||||
|
params.push(format!("q={name}"));
|
||||||
|
} else if let (Some(lat), Some(lon)) = (self.lat, self.lon) {
|
||||||
|
params.push(format!("lat={lat}&lon={lon}"));
|
||||||
|
} else if let Some(ref zip) = self.zip {
|
||||||
|
params.push(format!("zip={zip}"));
|
||||||
|
} else {
|
||||||
|
return Err("No valid location field found".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(format!("{base}?{}", params.join("&")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default values for query parameters
|
||||||
|
impl Default for QueryParams {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
api_key: String::new(),
|
||||||
|
city_id: None,
|
||||||
|
city_name: None,
|
||||||
|
lat: None,
|
||||||
|
lon: None,
|
||||||
|
zip: None,
|
||||||
|
units: Units::Standard,
|
||||||
|
lang: "en".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user