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"));
|
||||
//! ```
|
||||
|
||||
pub mod queryparams;
|
||||
pub mod units;
|
||||
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