openweather_async/
openweather.rs

1pub use crate::units::*;
2pub use crate::models::*;
3use std::error::Error;
4
5
6pub struct OpenWeather {
7    pub api_key: String,
8    pub units: Units,
9}
10
11
12impl OpenWeather {
13
14    pub async fn new(
15        api_key: &str,
16        units: Units
17    ) -> Result<OpenWeather, Box<dyn std::error::Error>> {
18        Ok(OpenWeather {
19            api_key: api_key.to_string(),
20            units: units,
21        })
22    }
23
24    async fn get_multiple(
25        &self,
26        query: String
27    ) -> Result<WeatherMultiple, Box<dyn Error>> {
28        let addr = self.format_addr(query).await?;
29        println!("{:?}", addr);
30        let response = self.get_response(&addr).await?;
31        println!("{:?}", response);
32        let data = self.parse_json_multiple(&response).await?;
33        Ok(data)
34    }
35
36    pub async fn get_by_city(
37        &self,
38        city: &str
39    ) -> Result<Weather, Box<dyn Error>> {
40        self.get(format!("weather?q={}", &city)).await
41    }
42
43
44    pub async fn get_by_city_and_country(
45        &self,
46        city: &str,
47        country: &str
48    ) -> Result<Weather, Box<dyn Error>> {
49        self.get(format!("weather?q={},{}", &city, &country)).await
50    }
51
52    pub async fn get_by_coordinates(
53        &self,
54        lat: f32,
55        lon: f32
56    ) -> Result<Weather, Box<dyn Error>> {
57        self.get(format!("weather?lat={}&lon={}", lat, lon)).await
58    }
59
60    pub async fn get_by_zipcode(
61        &self,
62        zipcode: u32,
63        country: &str,
64    ) -> Result<Weather, Box<dyn Error>> {
65        self.get(format!("weather?q={},{}", zipcode, country)).await
66    }
67
68    pub async fn get_by_cities_in_zone(
69        &self,
70        lon1: f32,
71        lat1: f32,
72        lon2: f32,
73        lat2: f32,
74        zoom: u32,
75    ) -> Result<WeatherMultiple, Box<dyn Error>> {
76        self.get_multiple(format!("box/city?bbox={},{},{},{},{}", lon1, lat1, lon2, lat2, zoom)).await
77    }
78
79    pub async fn get_by_cities_in_cycle(
80        &self,
81        lon: f32,
82        lat: f32,
83        count: u32,
84    ) -> Result<WeatherMultiple, Box<dyn Error>> {
85        self.get_multiple(format!("find?lat={}&lon={}&cnt={}", lon, lat, count)).await
86    }
87
88    async fn get(
89        &self,
90        query: String
91    ) -> Result<Weather, Box<dyn Error>> {
92        let addr = self.format_addr(query).await?;
93        println!("{:?}", addr);
94        let response = self.get_response(&addr).await?;
95        let data = self.parse_json(&response).await?;
96        Ok(data)
97    }
98
99    async fn format_addr(
100        &self,
101        query: String
102    ) -> Result<String, Box<dyn std::error::Error>> {
103        let base_http = "https://api.openweathermap.org/data/2.5/";
104        Ok(format!(
105            "{}{}&appid={}&units={}",
106            &base_http, &query, self.api_key, self.units.value()
107        ))
108    }
109
110    async fn get_response(
111        &self,
112        addr: &str
113    ) -> Result<String, reqwest::Error> {
114        let json = reqwest::get(addr).await?.text().await?;
115        Ok(json)
116    }
117
118    async fn parse_json(
119        &self,
120        json: &str
121    ) -> Result<Weather, serde_json::error::Error> {
122        let data: Weather = serde_json::from_str(&json.to_string())?;
123        Ok(data)
124    }
125
126    async fn parse_json_multiple(
127        &self,
128        json: &str
129    ) -> Result<WeatherMultiple, serde_json::error::Error> {
130        let data: WeatherMultiple = serde_json::from_str(&json.to_string())?;
131        println!("{:?}", data);
132        Ok(data)
133    }
134
135}