diff --git a/src/bar_modules/bar_module_weather.rs b/src/bar_modules/bar_module_weather.rs index e56ebc6..0ec6dfc 100644 --- a/src/bar_modules/bar_module_weather.rs +++ b/src/bar_modules/bar_module_weather.rs @@ -25,9 +25,17 @@ impl UnibarModuleWeather { // -------------------- fn get_current_temperature(&self) -> f32 { - let deg_c :f32 = self.weather_info["features"][0]["properties"]["temperature"]["value"] - .to_string().parse().unwrap(); + let deg_c :f32; + match self.weather_info { + serde_json::Value::Null => { + deg_c = 0.0; + } + _ => { + deg_c = self.weather_info["features"][0]["properties"]["temperature"]["value"] + .to_string().parse().unwrap(); + } + } match self.opts.weather_units { common::TemperatureUnits::Metric => return deg_c, common::TemperatureUnits::Imperial => return (deg_c * 9.0 / 5.0) + 32.0, @@ -161,30 +169,41 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather { let mut curl = Easy::new(); let mut url_string = Vec::new(); let mut curl_ret = Vec::new(); + let mut curl_err = false; url_string.push("https://api.weather.gov/stations/".to_owned()); url_string.push(self.opts.weather_station.to_owned()); url_string.push("/observations?limit=1".to_owned()); curl.url(url_string.concat().as_str()).unwrap(); - { - let mut list = List::new(); - list.append("User-Agent: Bar Weather (mahesh@heshapps.com)").unwrap(); - curl.http_headers(list).unwrap(); + let mut list = List::new(); + list.append("User-Agent: Bar Weather (mahesh@heshapps.com)").unwrap(); + curl.http_headers(list).unwrap(); + + // Scoped block to handle the data transfer (Credit: Gemini) + { let mut transfer = curl.transfer(); + // Configure callback to write received response transfer.write_function(|data| { curl_ret.extend_from_slice(data); Ok(data.len()) }).unwrap(); - transfer.perform().unwrap(); - } - if self.opts.debug { - println!("-----> curl_data - [{}]", std::str::from_utf8(&curl_ret).unwrap()); - } - self.weather_info = serde_json::from_str(str::from_utf8(&curl_ret).unwrap()).unwrap(); + // Perform the request once configured + if let Err(e) = transfer.perform() { + eprintln!("Curl error: {e}"); + curl_err = true; + } + } // transfer goes out of scope and cleans up here + + if !curl_err { + let curl_reg_str = String::from_utf8(curl_ret).unwrap_or_else(|_| { + "".to_string() + }); + self.weather_info = serde_json::from_str(curl_reg_str.as_str()).unwrap(); + } } // -------------------- @@ -198,12 +217,20 @@ impl bar_modules::BarModuleActions for UnibarModuleWeather { // -------------------- fn get_icon(&self) -> String { - // "icon": "https://api.weather.gov/icons/land/night/ovc?size=medium", - let re = Regex::new(r"(\w+)\?size").unwrap(); - let json_val = self.weather_info["features"][0]["properties"]["icon"].to_string(); - let caps = re.captures(&json_val).unwrap(); - return self.get_unicode_symbol(caps.get(1).unwrap().as_str()); + match self.weather_info { + serde_json::Value::Null => { + return "⁈".to_string(); + } + _ => { + // "icon": "https://api.weather.gov/icons/land/night/ovc?size=medium", + let re = Regex::new(r"(\w+)\?size").unwrap(); + let json_val = self.weather_info["features"][0]["properties"]["icon"].to_string(); + let caps = re.captures(&json_val).unwrap(); + + return self.get_unicode_symbol(caps.get(1).unwrap().as_str()); + } + } } }