├── .gitignore ├── src ├── city.rs ├── main.rs ├── condition_icons.rs ├── config.rs └── weather.rs ├── Cargo.toml ├── Makefile ├── LICENSE ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /src/city.rs: -------------------------------------------------------------------------------- 1 | use reqwest::Error; 2 | 3 | #[derive(Debug, serde::Deserialize)] 4 | struct IpInfo { 5 | city: Option, 6 | } 7 | 8 | pub fn default_city() -> Result, Error> { 9 | let response: IpInfo = reqwest::blocking::get("https://ipinfo.io/json")?.json()?; 10 | Ok(response.city) 11 | } 12 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rusty-forecast" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | reqwest = { version = "0.11", features = ["blocking", "json"] } 10 | serde = { version = "1.0", features = ["derive"] } 11 | serde_json = "1.0" 12 | dirs = "3.0" 13 | chrono = "0.4" -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .RECIPEPREFIX = > 2 | 3 | # Variables 4 | PROJECT_NAME = rusty-forecast 5 | RELEASE_BINARY = target/release/$(PROJECT_NAME) 6 | INSTALL_DIR = /usr/bin/ 7 | 8 | # Default target 9 | all: build 10 | 11 | # Build target 12 | build: 13 | > cargo build --release 14 | 15 | # Install target 16 | install: 17 | > cp $(RELEASE_BINARY) $(INSTALL_DIR) 18 | 19 | # Uninstall target 20 | uninstall: 21 | > rm -f $(INSTALL_DIR)/$(PROJECT_NAME) 22 | 23 | # Clean target 24 | clean: 25 | > cargo clean 26 | 27 | .PHONY: all build install uninstall clean 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Hussein Hareb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rusty-forecast 2 | rusty-forecast is a Linux CLI command for retrieving weather details. 3 | ## INSTALLATION 4 | 5 | ``` 6 | git clone https://github.com/husseinhareb/rusty-forecast/ 7 | cd rusty-forecast/ 8 | make build 9 | sudo make install 10 | ``` 11 | Note: Rust should be installed on your system to build the binary. 12 | ## USAGE 13 | ``` 14 | Usage: rusty-forecast [options] | rusty-forecast 15 | Options: 16 | -h Display this help message 17 | -c Change the city name 18 | -d Set the default city according to ip address 19 | -t Show more weather details of today 20 | -w Show weather forecast 21 | -s Show all configuration settings 22 | -u Set the unit of temperature (Celsius or Fahrenheit) 23 | -a Set the api key 24 | ``` 25 | ## Screenshots 26 | 27 | ![swappy-20240409_025831](https://github.com/husseinhareb/rusty-forecast/assets/88323940/9254dc3c-f69a-4cdd-97bf-f6cd81d99bbb) 28 | 29 | 30 | ## Contributing 31 | 32 | Contributions are welcome! If you'd like to contribute: 33 | 34 | Fork the repository. 35 | Create your branch: git checkout -b feature/YourFeature. 36 | Commit your changes: git commit -m 'Add some feature'. 37 | Push to the branch: git push origin feature/YourFeature. 38 | Submit a pull request. 39 | 40 | ## Licence 41 | 42 | This project is licensed under the [MIT License](https://github.com/husseinhareb/rusty-forecast/blob/main/LICENSE). 43 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | mod config; 4 | mod weather; 5 | mod city; 6 | mod condition_icons; 7 | 8 | fn help() { 9 | println!("Usage: rusty-forecast [options] | rusty-forecast"); 10 | println!("Options:"); 11 | println!("-h Display this help message"); 12 | println!("-c Change the city name"); 13 | println!("-d Set the default city according to timezone"); 14 | println!("-t Show more weather details of today"); 15 | println!("-w Show weather forecast"); 16 | println!("-s Show all configuration settings"); 17 | println!("-u Set the unit of temperature (Celsius or Fahrenheit)"); 18 | println!("-a Set the api key") 19 | } 20 | 21 | 22 | fn main() { 23 | let args: Vec = env::args().collect(); 24 | 25 | if args.len() == 1 { 26 | let _ = config::create_config(); 27 | let _ = weather::weather_now(); 28 | return; 29 | } 30 | 31 | let mut iter = args.iter().skip(1); // Skip the first argument (program name) 32 | 33 | while let Some(arg) = iter.next() { 34 | match arg.as_str() { 35 | "-h" => { 36 | help(); 37 | return; 38 | } 39 | "-c" => { 40 | if let Some(city_name) = iter.next().map(|s| s.to_owned()) { 41 | let _ = config::write_city_name(&city_name); 42 | let _ = weather::weather_now(); 43 | } else { 44 | eprintln!("City name not provided for the -c flag."); 45 | help(); 46 | return; 47 | } 48 | } 49 | "-d" => { 50 | if let Err(err) = config::write_def_city() { 51 | eprintln!("Error: {}", err); 52 | } 53 | } 54 | "-t" => { 55 | if let Err(err) = weather::weather_details() { 56 | eprintln!("Error: {}", err); 57 | } 58 | } 59 | "-w" => { 60 | if let Err(err) = weather::weather_forecast() { 61 | eprintln!("Error: {}", err); 62 | } 63 | } 64 | "-s" => { 65 | if let Err(err) = config::read_all_configs() { 66 | eprintln!("Error: {}", err); 67 | } 68 | } 69 | "-u" => { 70 | if let Some(unit_value) = iter.next() { 71 | if let Some(unit_char) = unit_value.chars().next() { 72 | let unit = unit_char.to_string(); // Convert char to String 73 | let _ = config::write_unit(&unit); 74 | } else { 75 | eprintln!("Invalid unit value provided. Use single characters 'C' or 'F'."); 76 | return; 77 | } 78 | } else { 79 | eprintln!("Unit value not provided for the -u flag."); 80 | help(); 81 | return; 82 | } 83 | } 84 | 85 | "-a" => { 86 | if let Some(api_key) = iter.next().map(|s| s.to_owned()) { 87 | let _ = config::write_api_key(&api_key); 88 | } else { 89 | eprintln!("Api key not provided for the -a flag."); 90 | help(); 91 | return; 92 | } 93 | } 94 | 95 | _ => { 96 | eprintln!("Invalid argument: {}", arg); 97 | help(); 98 | return; 99 | } 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /src/condition_icons.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug, PartialEq)] 2 | pub enum WeatherStatus { 3 | ClearSky, 4 | FewClouds, 5 | ScatteredClouds, 6 | BrokenClouds, 7 | ShowerRain, 8 | Rain, 9 | Thunderstorm, 10 | Snow, 11 | Mist, 12 | } 13 | 14 | impl WeatherStatus { 15 | pub fn from_weather_code(code: u16) -> Option { 16 | match code { 17 | 200..=202 | 210..=212 | 221 | 230..=232 => Some(WeatherStatus::Thunderstorm), 18 | 300..=302 | 310..=314 | 321 => Some(WeatherStatus::ShowerRain), 19 | 500 | 520 | 521 => Some(WeatherStatus::Rain), 20 | 501..=504 => Some(WeatherStatus::Rain), 21 | 511 => Some(WeatherStatus::Snow), 22 | 600..=601 | 611..=612 | 615..=616 | 620..=622 => Some(WeatherStatus::Snow), 23 | 701..=781 => Some(WeatherStatus::Mist), 24 | 800 => Some(WeatherStatus::ClearSky), 25 | 801 => Some(WeatherStatus::FewClouds), 26 | 802 => Some(WeatherStatus::ScatteredClouds), 27 | 803..=804 => Some(WeatherStatus::BrokenClouds), 28 | _ => None, 29 | } 30 | } 31 | 32 | pub fn icon(&self) -> &'static str { 33 | match self { 34 | WeatherStatus::ClearSky => "", 35 | WeatherStatus::FewClouds => "", 36 | WeatherStatus::ScatteredClouds => "", 37 | WeatherStatus::BrokenClouds => "", 38 | WeatherStatus::ShowerRain => "", 39 | WeatherStatus::Rain => "", 40 | WeatherStatus::Thunderstorm => "", 41 | WeatherStatus::Snow => "", 42 | WeatherStatus::Mist => "󰖑", 43 | } 44 | } 45 | } 46 | 47 | // Mapping from weather description to weather code 48 | pub fn map_weather_description_to_code(description: &str) -> Option { 49 | match description { 50 | "thunderstorm with light rain" => Some(200), 51 | "thunderstorm with rain" => Some(201), 52 | "thunderstorm with heavy rain" => Some(202), 53 | "light thunderstorm" => Some(210), 54 | "thunderstorm" => Some(211), 55 | "heavy thunderstorm" => Some(212), 56 | "ragged thunderstorm" => Some(221), 57 | "thunderstorm with light drizzle" => Some(230), 58 | "thunderstorm with drizzle" => Some(231), 59 | "thunderstorm with heavy drizzle" => Some(232), 60 | "light intensity drizzle" => Some(300), 61 | "drizzle" => Some(301), 62 | "heavy intensity drizzle" => Some(302), 63 | "light intensity drizzle rain" => Some(310), 64 | "drizzle rain" => Some(311), 65 | "heavy intensity drizzle rain" => Some(312), 66 | "shower rain and drizzle" => Some(313), 67 | "heavy shower rain and drizzle" => Some(314), 68 | "shower drizzle" => Some(321), 69 | "light rain" => Some(500), 70 | "moderate rain" => Some(501), 71 | "heavy intensity rain" => Some(502), 72 | "very heavy rain" => Some(503), 73 | "extreme rain" => Some(504), 74 | "freezing rain" => Some(511), 75 | "light intensity shower rain" => Some(520), 76 | "shower rain" => Some(521), 77 | "heavy intensity shower rain" => Some(522), 78 | "ragged shower rain" => Some(531), 79 | "light snow" => Some(600), 80 | "snow" => Some(601), 81 | "heavy snow" => Some(602), 82 | "sleet" => Some(611), 83 | "light shower sleet" => Some(612), 84 | "shower sleet" => Some(613), 85 | "light rain and snow" => Some(615), 86 | "rain and snow" => Some(616), 87 | "light shower snow" => Some(620), 88 | "shower snow" => Some(621), 89 | "heavy shower snow" => Some(622), 90 | "mist" => Some(701), 91 | "smoke" => Some(711), 92 | "haze" => Some(721), 93 | "sand/dust whirls" => Some(731), 94 | "fog" => Some(741), 95 | "sand" => Some(751), 96 | "dust" => Some(761), 97 | "volcanic ash" => Some(762), 98 | "squalls" => Some(771), 99 | "tornado" => Some(781), 100 | "clear sky" => Some(800), 101 | "few clouds" => Some(801), 102 | "scattered clouds" => Some(802), 103 | "broken clouds" => Some(803), 104 | "overcast clouds" => Some(804), 105 | _ => None, 106 | } 107 | } -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use std::fs::{self, File}; 2 | use std::path::PathBuf; 3 | use std::io::{self, prelude::*, BufRead, Write}; 4 | use crate::city::default_city; 5 | 6 | 7 | const GREEN: &str = "\x1b[32m"; 8 | const RESET: &str = "\x1b[0m"; 9 | 10 | // Function to create the config file if not created 11 | pub fn create_config() -> std::io::Result<()> { 12 | let config_dir = dirs::config_dir().expect("Unable to determine config directory"); 13 | let folder_path = config_dir.join("rusty-forecast"); 14 | 15 | if !folder_exists(&folder_path) { 16 | fs::create_dir(&folder_path)?; 17 | } 18 | 19 | let file_path = folder_path.join("rusty-forecast.conf"); 20 | 21 | if file_exists(&file_path) { 22 | Ok(()) 23 | } else { 24 | write_def_city()?; 25 | Ok(()) 26 | } 27 | } 28 | 29 | // Function to read all configs 30 | pub fn read_all_configs() -> io::Result { 31 | let file_path = config_file()?; 32 | 33 | let file = File::open(&file_path)?; 34 | let reader = io::BufReader::new(file); 35 | 36 | let mut config_content = String::new(); 37 | 38 | for line in reader.lines() { 39 | let line = line?; 40 | config_content.push_str(&line); 41 | config_content.push('\n'); 42 | println!("{}", line); 43 | } 44 | 45 | if config_content.is_empty() { 46 | return Err(io::Error::new(io::ErrorKind::NotFound, "Config content not found")); 47 | } 48 | 49 | Ok(config_content) 50 | } 51 | 52 | // Function to write city name according to parameter into the config file 53 | pub fn write_city_name(city_name: &str) -> io::Result<()> { 54 | let file_path = config_file()?; 55 | let mut file_content = String::new(); 56 | 57 | if file_path.exists() { 58 | let mut file = File::open(&file_path)?; 59 | file.read_to_string(&mut file_content)?; 60 | } 61 | 62 | let mut updated_content = String::new(); 63 | let mut city_found = false; 64 | 65 | for line in file_content.lines() { 66 | if line.trim().starts_with("city") { 67 | city_found = true; 68 | updated_content.push_str(&format!("city {}\n", city_name)); 69 | } else { 70 | updated_content.push_str(&line); 71 | updated_content.push('\n'); 72 | } 73 | } 74 | 75 | if !city_found { 76 | updated_content.push_str(&format!("city {}\n", city_name)); 77 | } 78 | 79 | let mut file = File::create(&file_path)?; 80 | file.write_all(updated_content.as_bytes())?; 81 | 82 | Ok(()) 83 | } 84 | 85 | // Function to read city name from config file 86 | pub fn read_city_name() -> io::Result { 87 | let file_path = config_file()?; 88 | let file = File::open(&file_path)?; 89 | let reader = io::BufReader::new(file); 90 | 91 | for line in reader.lines() { 92 | let line = line?; 93 | if line.trim().starts_with("city") { 94 | let city_name = line.split_whitespace().skip(1).collect::>().join(" "); 95 | return Ok(city_name); 96 | } 97 | } 98 | 99 | Err(io::Error::new(io::ErrorKind::NotFound, "City name not found")) 100 | } 101 | 102 | // Function to write api key according to parameter into the config file 103 | pub fn write_api_key(api_key: &str) -> io::Result<()> { 104 | let file_path = config_file()?; 105 | let mut file_content = String::new(); 106 | 107 | if file_path.exists() { 108 | let mut file = File::open(&file_path)?; 109 | file.read_to_string(&mut file_content)?; 110 | } 111 | 112 | let mut updated_content = String::new(); 113 | let mut api_found = false; 114 | 115 | for line in file_content.lines() { 116 | if line.trim().starts_with("api") { 117 | api_found = true; 118 | updated_content.push_str(&format!("api {}\n", api_key)); 119 | } else { 120 | updated_content.push_str(&line); 121 | updated_content.push('\n'); 122 | } 123 | } 124 | 125 | if !api_found { 126 | updated_content.push_str(&format!("api {}\n", api_key)); 127 | } 128 | 129 | let mut file = File::create(&file_path)?; 130 | file.write_all(updated_content.as_bytes())?; 131 | 132 | Ok(()) 133 | } 134 | 135 | // Function to read api key from config file 136 | pub fn read_api_key() -> io::Result { 137 | let file_path = config_file()?; 138 | let file = File::open(&file_path)?; 139 | let reader = io::BufReader::new(file); 140 | 141 | for line in reader.lines() { 142 | let line = line?; 143 | if line.trim().starts_with("api") { 144 | let api_key = line.split_whitespace().skip(1).collect::>().join(" "); 145 | return Ok(api_key); 146 | } 147 | } 148 | 149 | println!("Api Key not found.\nGet yours for free on {}https://openweathermap.org/{}.\n",GREEN,RESET); 150 | print!("Paste your api key here:"); 151 | let mut api_key = String::new(); 152 | io::stdin().read_line(&mut api_key)?; 153 | api_key = api_key.trim().to_string(); 154 | write_api_key(&api_key)?; 155 | Ok(api_key) 156 | } 157 | 158 | // Function to write unit value according to parameter into the config file 159 | pub fn write_unit(unit_value: &str) -> io::Result<()> { 160 | let file_path = config_file()?; 161 | let mut file_content = String::new(); 162 | 163 | if file_path.exists() { 164 | let mut file = File::open(&file_path)?; 165 | file.read_to_string(&mut file_content)?; 166 | } 167 | 168 | let mut updated_content = String::new(); 169 | let mut unit_found = false; 170 | 171 | for line in file_content.lines() { 172 | if line.trim().starts_with("unit") { 173 | unit_found = true; 174 | updated_content.push_str(&format!("unit {}\n", unit_value)); 175 | } else { 176 | updated_content.push_str(&line); 177 | updated_content.push('\n'); 178 | } 179 | } 180 | 181 | if !unit_found { 182 | updated_content.push_str(&format!("unit {}\n", unit_value)); 183 | } 184 | 185 | let mut file = File::create(&file_path)?; 186 | file.write_all(updated_content.as_bytes())?; 187 | 188 | Ok(()) 189 | } 190 | 191 | // Function to read unit value from config file 192 | pub fn read_unit() -> io::Result { 193 | let file_path = config_file()?; 194 | let file = File::open(&file_path)?; 195 | let reader = io::BufReader::new(file); 196 | 197 | for line in reader.lines() { 198 | let line = line?; 199 | if line.trim().starts_with("unit") { 200 | let unit_name = line.split_whitespace().skip(1).collect::>().join(" "); 201 | return Ok(unit_name); 202 | } 203 | } 204 | 205 | Err(io::Error::new(io::ErrorKind::NotFound, "Unit name not found")) 206 | } 207 | 208 | // Function to write default city according to the ip address into the config file 209 | pub fn write_def_city() -> io::Result<()> { 210 | let def_city = match default_city() { 211 | Ok(Some(city)) => city, 212 | Ok(None) => { 213 | return Err(io::Error::new(io::ErrorKind::Other, "Default city not found")); 214 | } 215 | Err(err) => { 216 | return Err(io::Error::new( 217 | io::ErrorKind::Other, 218 | format!("Failed to get default city: {}", err), 219 | )); 220 | } 221 | }; 222 | write_city_name(&def_city) 223 | } 224 | 225 | // Function to check if a folder exists 226 | fn folder_exists(folder_path: &PathBuf) -> bool { 227 | if let Ok(metadata) = std::fs::metadata(folder_path) { 228 | metadata.is_dir() 229 | } else { 230 | false 231 | } 232 | } 233 | 234 | // Function to check if a file exists 235 | fn file_exists(file_path: &PathBuf) -> bool { 236 | if let Ok(metadata) = std::fs::metadata(file_path) { 237 | metadata.is_file() 238 | } else { 239 | false 240 | } 241 | } 242 | 243 | // Function to get the path of the config file 244 | fn config_file() -> Result { 245 | let config_dir = match dirs::config_dir() { 246 | Some(path) => path, 247 | None => return Err(io::Error::new(io::ErrorKind::NotFound, "Config directory not found")), 248 | }; 249 | 250 | let file_path = config_dir.join("rusty-forecast").join("rusty-forecast.conf"); 251 | Ok(file_path) 252 | } 253 | -------------------------------------------------------------------------------- /src/weather.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | use crate::config::{read_city_name, read_unit,read_api_key}; 3 | use crate::condition_icons::WeatherStatus; 4 | use crate::condition_icons::map_weather_description_to_code; 5 | use chrono::{Local, TimeZone}; 6 | 7 | const GREEN: &str = "\x1b[32m"; 8 | 9 | const RESET: &str = "\x1b[0m"; 10 | const BOLD: &str = "\x1b[1m"; 11 | 12 | #[derive(Deserialize)] 13 | struct WeatherResponse { 14 | main: WeatherData, 15 | weather: Vec, 16 | sys: SysData, 17 | wind: WindData, 18 | visibility: f32, 19 | } 20 | 21 | #[derive(Deserialize)] 22 | struct WeatherData { 23 | temp: f32, 24 | humidity: f32, 25 | pressure: f32, 26 | feels_like: f32, 27 | temp_max: f32, 28 | temp_min: f32, 29 | } 30 | 31 | #[derive(Deserialize)] 32 | struct WeatherDescription { 33 | description: String, 34 | } 35 | 36 | #[derive(Deserialize)] 37 | struct SysData { 38 | sunrise: i64, 39 | sunset: i64, 40 | } 41 | 42 | 43 | #[derive(Deserialize)] 44 | struct WindData { 45 | deg: u16, 46 | speed: f32, 47 | } 48 | 49 | 50 | 51 | #[derive(Deserialize)] 52 | struct ForecastResponse { 53 | list: Vec, 54 | } 55 | 56 | #[derive(Deserialize)] 57 | struct ForecastData { 58 | dt_txt: String, 59 | main: WeatherData, 60 | weather: Vec, 61 | } 62 | 63 | 64 | //Function to print the weather of the 4 upcoming days 65 | pub fn weather_forecast() -> Result<(), Box> { 66 | let city_name = match read_city_name() { 67 | Ok(name) => name, 68 | Err(err) => { 69 | eprintln!("Error reading city name: {}", err); 70 | return Ok(()); 71 | } 72 | }; 73 | // Read unit value from config 74 | let unit_value = match read_unit() { 75 | Ok(name) => name, 76 | Err(err) => { 77 | eprintln!("Error reading unit value: {}", err); 78 | return Ok(()); 79 | } 80 | }; 81 | let api_key = read_api_key()?; 82 | // Determine unit type based on unit value 83 | let unit_type = if unit_value == "C" { 84 | "metric" 85 | } else { 86 | "imperial" 87 | }; 88 | 89 | let url = format!("http://api.openweathermap.org/data/2.5/forecast?q={}&appid={}&units={}", city_name, api_key,unit_type); 90 | 91 | let response = reqwest::blocking::get(&url)?.text()?; 92 | 93 | let data: serde_json::Value = serde_json::from_str(&response)?; 94 | 95 | if let Some(cod) = data["cod"].as_str() { 96 | if cod != "200" { 97 | println!("Error: {}", data["message"]); 98 | return Ok(()); 99 | } 100 | } else { 101 | println!("Error: 'cod' field not found in response"); 102 | return Ok(()); 103 | } 104 | 105 | let forecast: ForecastResponse = serde_json::from_value(data)?; 106 | 107 | println!("{}", city_name); 108 | 109 | for forecast_data in forecast.list.iter().step_by(8).take(4) { let weather_description = match forecast_data.weather.get(0) { 110 | Some(desc) => &desc.description, 111 | None => { 112 | println!("No weather description available"); 113 | return Ok(()); 114 | } 115 | }; 116 | 117 | let weather_code = match map_weather_description_to_code(&weather_description) { 118 | Some(code) => code, 119 | None => { 120 | println!("Unknown weather description"); 121 | return Ok(()); 122 | } 123 | }; 124 | 125 | let weather_status = match WeatherStatus::from_weather_code(weather_code) { 126 | Some(status) => status, 127 | None => { 128 | println!("Unsupported weather code"); 129 | return Ok(()); 130 | } 131 | }; 132 | 133 | let date_time = &forecast_data.dt_txt; 134 | let date = &date_time.split(' ').collect::>()[0]; 135 | 136 | let formatted_temp = format!("{}°{}", forecast_data.main.temp, unit_value); 137 | let formatted_humidity = format!("{}%", forecast_data.main.humidity); 138 | 139 | let temp_box = [ 140 | "╔══════════════════╗", 141 | &format!("║{: ^18}║", date), 142 | &format!("║{: ^18}║", weather_status.icon()), 143 | &format!("║{: ^18}║", formatted_temp), 144 | &format!("║{: ^18}║", formatted_humidity), 145 | "╚══════════════════╝", 146 | ].join("\n"); 147 | 148 | println!("{}", temp_box); 149 | 150 | 151 | } 152 | 153 | Ok(()) 154 | } 155 | 156 | 157 | fn fetch_weather_data() -> Result> { 158 | 159 | let city_name = read_city_name()?; 160 | let unit_value = read_unit()?; 161 | let api_key = read_api_key()?; 162 | let unit_type = if unit_value == "C" { 163 | "metric" 164 | } else { 165 | "imperial" 166 | }; 167 | 168 | let url = format!( 169 | "http://api.openweathermap.org/data/2.5/weather?q={}&appid={}&units={}", 170 | city_name, api_key, unit_type 171 | ); 172 | 173 | let response: serde_json::Value = reqwest::blocking::get(&url)?.json()?; 174 | if response["cod"] != 200 { 175 | return Err(format!("Error: {}", response["message"]).into()); 176 | } 177 | serde_json::from_value(response).map_err(Into::into) 178 | } 179 | 180 | 181 | //Function to fetch the weather now 182 | pub fn weather_now() -> Result<(), Box> { 183 | let weather = match fetch_weather_data() { 184 | Ok(weather) => weather, 185 | Err(err) => { 186 | eprintln!("Error fetching weather data: {}", err); 187 | return Ok(()); 188 | } 189 | }; 190 | 191 | let weather_description = match weather.weather.get(0) { 192 | Some(desc) => &desc.description, 193 | None => { 194 | println!("No weather description available"); 195 | return Ok(()); 196 | } 197 | }; 198 | 199 | let weather_code = match map_weather_description_to_code(&weather_description) { 200 | Some(code) => code, 201 | None => { 202 | println!("Unknown weather description"); 203 | return Ok(()); 204 | } 205 | }; 206 | 207 | let weather_status = match WeatherStatus::from_weather_code(weather_code) { 208 | Some(status) => status, 209 | None => { 210 | println!("Unsupported weather code"); 211 | return Ok(()); 212 | } 213 | }; 214 | 215 | let formatted_temp = format!(" {}°{}", weather.main.temp, read_unit()?); 216 | let formatted_humidity = format!(" {}%", weather.main.humidity); 217 | println!("•{}", read_city_name()?); 218 | let temp_box = [ 219 | "╔══════════════════╗", 220 | &format!("║{: ^18}║", weather_status.icon()), 221 | &format!("║{: ^18}║", weather.weather[0].description), 222 | &format!("║{: ^18}║", formatted_temp), 223 | &format!("║{: ^18}║", formatted_humidity), 224 | "╚══════════════════╝", 225 | ].join("\n"); 226 | 227 | println!("{}", temp_box); 228 | 229 | Ok(()) 230 | } 231 | 232 | 233 | //Function to fetch more info about the weather now 234 | pub fn weather_details() -> Result<(), Box> { 235 | 236 | let weather = fetch_weather_data()?; 237 | println!("{}{}•City: {}{}",GREEN,BOLD,RESET, read_city_name()?); 238 | println!("{}{}•Temperature: {}{}°{}",GREEN,BOLD,RESET, weather.main.temp, read_unit()?); 239 | println!("{}{}•Feels Like: {}{}°{}",GREEN,BOLD,RESET, weather.main.feels_like, read_unit()?); 240 | println!("{}{}•Weather Description: {}{}",GREEN,BOLD,RESET, weather.weather[0].description); 241 | println!("{}{}•Minimum Temperature: {}{}°{}",GREEN,BOLD,RESET, weather.main.temp_min, read_unit()?); 242 | println!("{}{}•Maximum Temperature: {}{}°{}",GREEN,BOLD,RESET, weather.main.temp_max, read_unit()?); 243 | println!("{}{}•Humidity: {}{}%",GREEN,BOLD,RESET, weather.main.humidity); 244 | println!("{}{}•Pressure: {}{} hPa",GREEN,BOLD,RESET, weather.main.pressure); 245 | println!("{}{}•Sunrise: {}{}",GREEN,BOLD,RESET, unix_time_to_datetime(weather.sys.sunrise)); 246 | println!("{}{}•Sunset: {}{}",GREEN,BOLD,RESET, unix_time_to_datetime(weather.sys.sunset)); 247 | println!("{}{}•Visibily: {}{}m",GREEN,BOLD,RESET, weather.visibility); 248 | println!("{}{}•Wind Degree: {}{}°",GREEN,BOLD,RESET, weather.wind.deg); 249 | let speed_value = if read_unit()? == "C" { "m/s" } else { "miles/h" }; 250 | println!("{}{}•Wind Speed: {}{} {}",GREEN,BOLD,RESET, weather.wind.speed,speed_value); 251 | Ok(()) 252 | } 253 | 254 | 255 | // Function to convert Unix time to local datetime 256 | fn unix_time_to_datetime(timestamp: i64) -> String { 257 | match Local.timestamp_opt(timestamp, 0) { 258 | chrono::LocalResult::Single(local_datetime) => { 259 | local_datetime.format("%H:%M:%S").to_string() 260 | } 261 | chrono::LocalResult::None => { 262 | "Invalid timestamp".to_string() 263 | } 264 | chrono::LocalResult::Ambiguous(_, _) => { 265 | "Ambiguous timestamp".to_string() 266 | } 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.21.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "android-tzdata" 22 | version = "0.1.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 25 | 26 | [[package]] 27 | name = "android_system_properties" 28 | version = "0.1.5" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 31 | dependencies = [ 32 | "libc", 33 | ] 34 | 35 | [[package]] 36 | name = "autocfg" 37 | version = "1.2.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" 40 | 41 | [[package]] 42 | name = "backtrace" 43 | version = "0.3.71" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" 46 | dependencies = [ 47 | "addr2line", 48 | "cc", 49 | "cfg-if", 50 | "libc", 51 | "miniz_oxide", 52 | "object", 53 | "rustc-demangle", 54 | ] 55 | 56 | [[package]] 57 | name = "base64" 58 | version = "0.21.7" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 61 | 62 | [[package]] 63 | name = "bitflags" 64 | version = "1.3.2" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 67 | 68 | [[package]] 69 | name = "bitflags" 70 | version = "2.5.0" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" 73 | 74 | [[package]] 75 | name = "bumpalo" 76 | version = "3.15.4" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" 79 | 80 | [[package]] 81 | name = "bytes" 82 | version = "1.6.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 85 | 86 | [[package]] 87 | name = "cc" 88 | version = "1.0.91" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "1fd97381a8cc6493395a5afc4c691c1084b3768db713b73aa215217aa245d153" 91 | 92 | [[package]] 93 | name = "cfg-if" 94 | version = "1.0.0" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 97 | 98 | [[package]] 99 | name = "chrono" 100 | version = "0.4.37" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" 103 | dependencies = [ 104 | "android-tzdata", 105 | "iana-time-zone", 106 | "js-sys", 107 | "num-traits", 108 | "wasm-bindgen", 109 | "windows-targets 0.52.4", 110 | ] 111 | 112 | [[package]] 113 | name = "core-foundation" 114 | version = "0.9.4" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 117 | dependencies = [ 118 | "core-foundation-sys", 119 | "libc", 120 | ] 121 | 122 | [[package]] 123 | name = "core-foundation-sys" 124 | version = "0.8.6" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 127 | 128 | [[package]] 129 | name = "dirs" 130 | version = "3.0.2" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" 133 | dependencies = [ 134 | "dirs-sys", 135 | ] 136 | 137 | [[package]] 138 | name = "dirs-sys" 139 | version = "0.3.7" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 142 | dependencies = [ 143 | "libc", 144 | "redox_users", 145 | "winapi", 146 | ] 147 | 148 | [[package]] 149 | name = "encoding_rs" 150 | version = "0.8.33" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" 153 | dependencies = [ 154 | "cfg-if", 155 | ] 156 | 157 | [[package]] 158 | name = "equivalent" 159 | version = "1.0.1" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 162 | 163 | [[package]] 164 | name = "errno" 165 | version = "0.3.8" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 168 | dependencies = [ 169 | "libc", 170 | "windows-sys 0.52.0", 171 | ] 172 | 173 | [[package]] 174 | name = "fastrand" 175 | version = "2.0.2" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" 178 | 179 | [[package]] 180 | name = "fnv" 181 | version = "1.0.7" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 184 | 185 | [[package]] 186 | name = "foreign-types" 187 | version = "0.3.2" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 190 | dependencies = [ 191 | "foreign-types-shared", 192 | ] 193 | 194 | [[package]] 195 | name = "foreign-types-shared" 196 | version = "0.1.1" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 199 | 200 | [[package]] 201 | name = "form_urlencoded" 202 | version = "1.2.1" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 205 | dependencies = [ 206 | "percent-encoding", 207 | ] 208 | 209 | [[package]] 210 | name = "futures-channel" 211 | version = "0.3.30" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 214 | dependencies = [ 215 | "futures-core", 216 | ] 217 | 218 | [[package]] 219 | name = "futures-core" 220 | version = "0.3.30" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 223 | 224 | [[package]] 225 | name = "futures-io" 226 | version = "0.3.30" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 229 | 230 | [[package]] 231 | name = "futures-sink" 232 | version = "0.3.30" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 235 | 236 | [[package]] 237 | name = "futures-task" 238 | version = "0.3.30" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 241 | 242 | [[package]] 243 | name = "futures-util" 244 | version = "0.3.30" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 247 | dependencies = [ 248 | "futures-core", 249 | "futures-io", 250 | "futures-task", 251 | "memchr", 252 | "pin-project-lite", 253 | "pin-utils", 254 | "slab", 255 | ] 256 | 257 | [[package]] 258 | name = "getrandom" 259 | version = "0.2.13" 260 | source = "registry+https://github.com/rust-lang/crates.io-index" 261 | checksum = "a06fddc2749e0528d2813f95e050e87e52c8cbbae56223b9babf73b3e53b0cc6" 262 | dependencies = [ 263 | "cfg-if", 264 | "libc", 265 | "wasi", 266 | ] 267 | 268 | [[package]] 269 | name = "gimli" 270 | version = "0.28.1" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 273 | 274 | [[package]] 275 | name = "h2" 276 | version = "0.3.26" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 279 | dependencies = [ 280 | "bytes", 281 | "fnv", 282 | "futures-core", 283 | "futures-sink", 284 | "futures-util", 285 | "http", 286 | "indexmap", 287 | "slab", 288 | "tokio", 289 | "tokio-util", 290 | "tracing", 291 | ] 292 | 293 | [[package]] 294 | name = "hashbrown" 295 | version = "0.14.3" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 298 | 299 | [[package]] 300 | name = "http" 301 | version = "0.2.12" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 304 | dependencies = [ 305 | "bytes", 306 | "fnv", 307 | "itoa", 308 | ] 309 | 310 | [[package]] 311 | name = "http-body" 312 | version = "0.4.6" 313 | source = "registry+https://github.com/rust-lang/crates.io-index" 314 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 315 | dependencies = [ 316 | "bytes", 317 | "http", 318 | "pin-project-lite", 319 | ] 320 | 321 | [[package]] 322 | name = "httparse" 323 | version = "1.8.0" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 326 | 327 | [[package]] 328 | name = "httpdate" 329 | version = "1.0.3" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 332 | 333 | [[package]] 334 | name = "hyper" 335 | version = "0.14.28" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 338 | dependencies = [ 339 | "bytes", 340 | "futures-channel", 341 | "futures-core", 342 | "futures-util", 343 | "h2", 344 | "http", 345 | "http-body", 346 | "httparse", 347 | "httpdate", 348 | "itoa", 349 | "pin-project-lite", 350 | "socket2", 351 | "tokio", 352 | "tower-service", 353 | "tracing", 354 | "want", 355 | ] 356 | 357 | [[package]] 358 | name = "hyper-tls" 359 | version = "0.5.0" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 362 | dependencies = [ 363 | "bytes", 364 | "hyper", 365 | "native-tls", 366 | "tokio", 367 | "tokio-native-tls", 368 | ] 369 | 370 | [[package]] 371 | name = "iana-time-zone" 372 | version = "0.1.60" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" 375 | dependencies = [ 376 | "android_system_properties", 377 | "core-foundation-sys", 378 | "iana-time-zone-haiku", 379 | "js-sys", 380 | "wasm-bindgen", 381 | "windows-core", 382 | ] 383 | 384 | [[package]] 385 | name = "iana-time-zone-haiku" 386 | version = "0.1.2" 387 | source = "registry+https://github.com/rust-lang/crates.io-index" 388 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 389 | dependencies = [ 390 | "cc", 391 | ] 392 | 393 | [[package]] 394 | name = "idna" 395 | version = "0.5.0" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 398 | dependencies = [ 399 | "unicode-bidi", 400 | "unicode-normalization", 401 | ] 402 | 403 | [[package]] 404 | name = "indexmap" 405 | version = "2.2.6" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 408 | dependencies = [ 409 | "equivalent", 410 | "hashbrown", 411 | ] 412 | 413 | [[package]] 414 | name = "ipnet" 415 | version = "2.9.0" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" 418 | 419 | [[package]] 420 | name = "itoa" 421 | version = "1.0.11" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 424 | 425 | [[package]] 426 | name = "js-sys" 427 | version = "0.3.69" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 430 | dependencies = [ 431 | "wasm-bindgen", 432 | ] 433 | 434 | [[package]] 435 | name = "lazy_static" 436 | version = "1.4.0" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 439 | 440 | [[package]] 441 | name = "libc" 442 | version = "0.2.153" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 445 | 446 | [[package]] 447 | name = "libredox" 448 | version = "0.1.3" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" 451 | dependencies = [ 452 | "bitflags 2.5.0", 453 | "libc", 454 | ] 455 | 456 | [[package]] 457 | name = "linux-raw-sys" 458 | version = "0.4.13" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 461 | 462 | [[package]] 463 | name = "log" 464 | version = "0.4.21" 465 | source = "registry+https://github.com/rust-lang/crates.io-index" 466 | checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 467 | 468 | [[package]] 469 | name = "memchr" 470 | version = "2.7.2" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" 473 | 474 | [[package]] 475 | name = "mime" 476 | version = "0.3.17" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 479 | 480 | [[package]] 481 | name = "miniz_oxide" 482 | version = "0.7.2" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 485 | dependencies = [ 486 | "adler", 487 | ] 488 | 489 | [[package]] 490 | name = "mio" 491 | version = "0.8.11" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 494 | dependencies = [ 495 | "libc", 496 | "wasi", 497 | "windows-sys 0.48.0", 498 | ] 499 | 500 | [[package]] 501 | name = "native-tls" 502 | version = "0.2.11" 503 | source = "registry+https://github.com/rust-lang/crates.io-index" 504 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 505 | dependencies = [ 506 | "lazy_static", 507 | "libc", 508 | "log", 509 | "openssl", 510 | "openssl-probe", 511 | "openssl-sys", 512 | "schannel", 513 | "security-framework", 514 | "security-framework-sys", 515 | "tempfile", 516 | ] 517 | 518 | [[package]] 519 | name = "num-traits" 520 | version = "0.2.18" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 523 | dependencies = [ 524 | "autocfg", 525 | ] 526 | 527 | [[package]] 528 | name = "object" 529 | version = "0.32.2" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 532 | dependencies = [ 533 | "memchr", 534 | ] 535 | 536 | [[package]] 537 | name = "once_cell" 538 | version = "1.19.0" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 541 | 542 | [[package]] 543 | name = "openssl" 544 | version = "0.10.64" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" 547 | dependencies = [ 548 | "bitflags 2.5.0", 549 | "cfg-if", 550 | "foreign-types", 551 | "libc", 552 | "once_cell", 553 | "openssl-macros", 554 | "openssl-sys", 555 | ] 556 | 557 | [[package]] 558 | name = "openssl-macros" 559 | version = "0.1.1" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 562 | dependencies = [ 563 | "proc-macro2", 564 | "quote", 565 | "syn", 566 | ] 567 | 568 | [[package]] 569 | name = "openssl-probe" 570 | version = "0.1.5" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 573 | 574 | [[package]] 575 | name = "openssl-sys" 576 | version = "0.9.102" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" 579 | dependencies = [ 580 | "cc", 581 | "libc", 582 | "pkg-config", 583 | "vcpkg", 584 | ] 585 | 586 | [[package]] 587 | name = "percent-encoding" 588 | version = "2.3.1" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 591 | 592 | [[package]] 593 | name = "pin-project-lite" 594 | version = "0.2.14" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 597 | 598 | [[package]] 599 | name = "pin-utils" 600 | version = "0.1.0" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 603 | 604 | [[package]] 605 | name = "pkg-config" 606 | version = "0.3.30" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 609 | 610 | [[package]] 611 | name = "proc-macro2" 612 | version = "1.0.79" 613 | source = "registry+https://github.com/rust-lang/crates.io-index" 614 | checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" 615 | dependencies = [ 616 | "unicode-ident", 617 | ] 618 | 619 | [[package]] 620 | name = "quote" 621 | version = "1.0.35" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 624 | dependencies = [ 625 | "proc-macro2", 626 | ] 627 | 628 | [[package]] 629 | name = "redox_users" 630 | version = "0.4.5" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" 633 | dependencies = [ 634 | "getrandom", 635 | "libredox", 636 | "thiserror", 637 | ] 638 | 639 | [[package]] 640 | name = "reqwest" 641 | version = "0.11.27" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" 644 | dependencies = [ 645 | "base64", 646 | "bytes", 647 | "encoding_rs", 648 | "futures-core", 649 | "futures-util", 650 | "h2", 651 | "http", 652 | "http-body", 653 | "hyper", 654 | "hyper-tls", 655 | "ipnet", 656 | "js-sys", 657 | "log", 658 | "mime", 659 | "native-tls", 660 | "once_cell", 661 | "percent-encoding", 662 | "pin-project-lite", 663 | "rustls-pemfile", 664 | "serde", 665 | "serde_json", 666 | "serde_urlencoded", 667 | "sync_wrapper", 668 | "system-configuration", 669 | "tokio", 670 | "tokio-native-tls", 671 | "tower-service", 672 | "url", 673 | "wasm-bindgen", 674 | "wasm-bindgen-futures", 675 | "web-sys", 676 | "winreg", 677 | ] 678 | 679 | [[package]] 680 | name = "rustc-demangle" 681 | version = "0.1.23" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 684 | 685 | [[package]] 686 | name = "rustix" 687 | version = "0.38.32" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" 690 | dependencies = [ 691 | "bitflags 2.5.0", 692 | "errno", 693 | "libc", 694 | "linux-raw-sys", 695 | "windows-sys 0.52.0", 696 | ] 697 | 698 | [[package]] 699 | name = "rustls-pemfile" 700 | version = "1.0.4" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 703 | dependencies = [ 704 | "base64", 705 | ] 706 | 707 | [[package]] 708 | name = "rusty-forecast" 709 | version = "0.1.0" 710 | dependencies = [ 711 | "chrono", 712 | "dirs", 713 | "reqwest", 714 | "serde", 715 | "serde_json", 716 | ] 717 | 718 | [[package]] 719 | name = "ryu" 720 | version = "1.0.17" 721 | source = "registry+https://github.com/rust-lang/crates.io-index" 722 | checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" 723 | 724 | [[package]] 725 | name = "schannel" 726 | version = "0.1.23" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" 729 | dependencies = [ 730 | "windows-sys 0.52.0", 731 | ] 732 | 733 | [[package]] 734 | name = "security-framework" 735 | version = "2.10.0" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" 738 | dependencies = [ 739 | "bitflags 1.3.2", 740 | "core-foundation", 741 | "core-foundation-sys", 742 | "libc", 743 | "security-framework-sys", 744 | ] 745 | 746 | [[package]] 747 | name = "security-framework-sys" 748 | version = "2.10.0" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" 751 | dependencies = [ 752 | "core-foundation-sys", 753 | "libc", 754 | ] 755 | 756 | [[package]] 757 | name = "serde" 758 | version = "1.0.197" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" 761 | dependencies = [ 762 | "serde_derive", 763 | ] 764 | 765 | [[package]] 766 | name = "serde_derive" 767 | version = "1.0.197" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" 770 | dependencies = [ 771 | "proc-macro2", 772 | "quote", 773 | "syn", 774 | ] 775 | 776 | [[package]] 777 | name = "serde_json" 778 | version = "1.0.115" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" 781 | dependencies = [ 782 | "itoa", 783 | "ryu", 784 | "serde", 785 | ] 786 | 787 | [[package]] 788 | name = "serde_urlencoded" 789 | version = "0.7.1" 790 | source = "registry+https://github.com/rust-lang/crates.io-index" 791 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 792 | dependencies = [ 793 | "form_urlencoded", 794 | "itoa", 795 | "ryu", 796 | "serde", 797 | ] 798 | 799 | [[package]] 800 | name = "slab" 801 | version = "0.4.9" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 804 | dependencies = [ 805 | "autocfg", 806 | ] 807 | 808 | [[package]] 809 | name = "socket2" 810 | version = "0.5.6" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" 813 | dependencies = [ 814 | "libc", 815 | "windows-sys 0.52.0", 816 | ] 817 | 818 | [[package]] 819 | name = "syn" 820 | version = "2.0.58" 821 | source = "registry+https://github.com/rust-lang/crates.io-index" 822 | checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" 823 | dependencies = [ 824 | "proc-macro2", 825 | "quote", 826 | "unicode-ident", 827 | ] 828 | 829 | [[package]] 830 | name = "sync_wrapper" 831 | version = "0.1.2" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 834 | 835 | [[package]] 836 | name = "system-configuration" 837 | version = "0.5.1" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 840 | dependencies = [ 841 | "bitflags 1.3.2", 842 | "core-foundation", 843 | "system-configuration-sys", 844 | ] 845 | 846 | [[package]] 847 | name = "system-configuration-sys" 848 | version = "0.5.0" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 851 | dependencies = [ 852 | "core-foundation-sys", 853 | "libc", 854 | ] 855 | 856 | [[package]] 857 | name = "tempfile" 858 | version = "3.10.1" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" 861 | dependencies = [ 862 | "cfg-if", 863 | "fastrand", 864 | "rustix", 865 | "windows-sys 0.52.0", 866 | ] 867 | 868 | [[package]] 869 | name = "thiserror" 870 | version = "1.0.58" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" 873 | dependencies = [ 874 | "thiserror-impl", 875 | ] 876 | 877 | [[package]] 878 | name = "thiserror-impl" 879 | version = "1.0.58" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" 882 | dependencies = [ 883 | "proc-macro2", 884 | "quote", 885 | "syn", 886 | ] 887 | 888 | [[package]] 889 | name = "tinyvec" 890 | version = "1.6.0" 891 | source = "registry+https://github.com/rust-lang/crates.io-index" 892 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 893 | dependencies = [ 894 | "tinyvec_macros", 895 | ] 896 | 897 | [[package]] 898 | name = "tinyvec_macros" 899 | version = "0.1.1" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 902 | 903 | [[package]] 904 | name = "tokio" 905 | version = "1.37.0" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" 908 | dependencies = [ 909 | "backtrace", 910 | "bytes", 911 | "libc", 912 | "mio", 913 | "pin-project-lite", 914 | "socket2", 915 | "windows-sys 0.48.0", 916 | ] 917 | 918 | [[package]] 919 | name = "tokio-native-tls" 920 | version = "0.3.1" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 923 | dependencies = [ 924 | "native-tls", 925 | "tokio", 926 | ] 927 | 928 | [[package]] 929 | name = "tokio-util" 930 | version = "0.7.10" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 933 | dependencies = [ 934 | "bytes", 935 | "futures-core", 936 | "futures-sink", 937 | "pin-project-lite", 938 | "tokio", 939 | "tracing", 940 | ] 941 | 942 | [[package]] 943 | name = "tower-service" 944 | version = "0.3.2" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 947 | 948 | [[package]] 949 | name = "tracing" 950 | version = "0.1.40" 951 | source = "registry+https://github.com/rust-lang/crates.io-index" 952 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 953 | dependencies = [ 954 | "pin-project-lite", 955 | "tracing-core", 956 | ] 957 | 958 | [[package]] 959 | name = "tracing-core" 960 | version = "0.1.32" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 963 | dependencies = [ 964 | "once_cell", 965 | ] 966 | 967 | [[package]] 968 | name = "try-lock" 969 | version = "0.2.5" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 972 | 973 | [[package]] 974 | name = "unicode-bidi" 975 | version = "0.3.15" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 978 | 979 | [[package]] 980 | name = "unicode-ident" 981 | version = "1.0.12" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 984 | 985 | [[package]] 986 | name = "unicode-normalization" 987 | version = "0.1.23" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 990 | dependencies = [ 991 | "tinyvec", 992 | ] 993 | 994 | [[package]] 995 | name = "url" 996 | version = "2.5.0" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 999 | dependencies = [ 1000 | "form_urlencoded", 1001 | "idna", 1002 | "percent-encoding", 1003 | ] 1004 | 1005 | [[package]] 1006 | name = "vcpkg" 1007 | version = "0.2.15" 1008 | source = "registry+https://github.com/rust-lang/crates.io-index" 1009 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1010 | 1011 | [[package]] 1012 | name = "want" 1013 | version = "0.3.1" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1016 | dependencies = [ 1017 | "try-lock", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "wasi" 1022 | version = "0.11.0+wasi-snapshot-preview1" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1025 | 1026 | [[package]] 1027 | name = "wasm-bindgen" 1028 | version = "0.2.92" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 1031 | dependencies = [ 1032 | "cfg-if", 1033 | "wasm-bindgen-macro", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "wasm-bindgen-backend" 1038 | version = "0.2.92" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 1041 | dependencies = [ 1042 | "bumpalo", 1043 | "log", 1044 | "once_cell", 1045 | "proc-macro2", 1046 | "quote", 1047 | "syn", 1048 | "wasm-bindgen-shared", 1049 | ] 1050 | 1051 | [[package]] 1052 | name = "wasm-bindgen-futures" 1053 | version = "0.4.42" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" 1056 | dependencies = [ 1057 | "cfg-if", 1058 | "js-sys", 1059 | "wasm-bindgen", 1060 | "web-sys", 1061 | ] 1062 | 1063 | [[package]] 1064 | name = "wasm-bindgen-macro" 1065 | version = "0.2.92" 1066 | source = "registry+https://github.com/rust-lang/crates.io-index" 1067 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 1068 | dependencies = [ 1069 | "quote", 1070 | "wasm-bindgen-macro-support", 1071 | ] 1072 | 1073 | [[package]] 1074 | name = "wasm-bindgen-macro-support" 1075 | version = "0.2.92" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 1078 | dependencies = [ 1079 | "proc-macro2", 1080 | "quote", 1081 | "syn", 1082 | "wasm-bindgen-backend", 1083 | "wasm-bindgen-shared", 1084 | ] 1085 | 1086 | [[package]] 1087 | name = "wasm-bindgen-shared" 1088 | version = "0.2.92" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 1091 | 1092 | [[package]] 1093 | name = "web-sys" 1094 | version = "0.3.69" 1095 | source = "registry+https://github.com/rust-lang/crates.io-index" 1096 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 1097 | dependencies = [ 1098 | "js-sys", 1099 | "wasm-bindgen", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "winapi" 1104 | version = "0.3.9" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1107 | dependencies = [ 1108 | "winapi-i686-pc-windows-gnu", 1109 | "winapi-x86_64-pc-windows-gnu", 1110 | ] 1111 | 1112 | [[package]] 1113 | name = "winapi-i686-pc-windows-gnu" 1114 | version = "0.4.0" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1117 | 1118 | [[package]] 1119 | name = "winapi-x86_64-pc-windows-gnu" 1120 | version = "0.4.0" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1123 | 1124 | [[package]] 1125 | name = "windows-core" 1126 | version = "0.52.0" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 1129 | dependencies = [ 1130 | "windows-targets 0.52.4", 1131 | ] 1132 | 1133 | [[package]] 1134 | name = "windows-sys" 1135 | version = "0.48.0" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1138 | dependencies = [ 1139 | "windows-targets 0.48.5", 1140 | ] 1141 | 1142 | [[package]] 1143 | name = "windows-sys" 1144 | version = "0.52.0" 1145 | source = "registry+https://github.com/rust-lang/crates.io-index" 1146 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1147 | dependencies = [ 1148 | "windows-targets 0.52.4", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "windows-targets" 1153 | version = "0.48.5" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 1156 | dependencies = [ 1157 | "windows_aarch64_gnullvm 0.48.5", 1158 | "windows_aarch64_msvc 0.48.5", 1159 | "windows_i686_gnu 0.48.5", 1160 | "windows_i686_msvc 0.48.5", 1161 | "windows_x86_64_gnu 0.48.5", 1162 | "windows_x86_64_gnullvm 0.48.5", 1163 | "windows_x86_64_msvc 0.48.5", 1164 | ] 1165 | 1166 | [[package]] 1167 | name = "windows-targets" 1168 | version = "0.52.4" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" 1171 | dependencies = [ 1172 | "windows_aarch64_gnullvm 0.52.4", 1173 | "windows_aarch64_msvc 0.52.4", 1174 | "windows_i686_gnu 0.52.4", 1175 | "windows_i686_msvc 0.52.4", 1176 | "windows_x86_64_gnu 0.52.4", 1177 | "windows_x86_64_gnullvm 0.52.4", 1178 | "windows_x86_64_msvc 0.52.4", 1179 | ] 1180 | 1181 | [[package]] 1182 | name = "windows_aarch64_gnullvm" 1183 | version = "0.48.5" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 1186 | 1187 | [[package]] 1188 | name = "windows_aarch64_gnullvm" 1189 | version = "0.52.4" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" 1192 | 1193 | [[package]] 1194 | name = "windows_aarch64_msvc" 1195 | version = "0.48.5" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 1198 | 1199 | [[package]] 1200 | name = "windows_aarch64_msvc" 1201 | version = "0.52.4" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" 1204 | 1205 | [[package]] 1206 | name = "windows_i686_gnu" 1207 | version = "0.48.5" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 1210 | 1211 | [[package]] 1212 | name = "windows_i686_gnu" 1213 | version = "0.52.4" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" 1216 | 1217 | [[package]] 1218 | name = "windows_i686_msvc" 1219 | version = "0.48.5" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 1222 | 1223 | [[package]] 1224 | name = "windows_i686_msvc" 1225 | version = "0.52.4" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" 1228 | 1229 | [[package]] 1230 | name = "windows_x86_64_gnu" 1231 | version = "0.48.5" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 1234 | 1235 | [[package]] 1236 | name = "windows_x86_64_gnu" 1237 | version = "0.52.4" 1238 | source = "registry+https://github.com/rust-lang/crates.io-index" 1239 | checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" 1240 | 1241 | [[package]] 1242 | name = "windows_x86_64_gnullvm" 1243 | version = "0.48.5" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 1246 | 1247 | [[package]] 1248 | name = "windows_x86_64_gnullvm" 1249 | version = "0.52.4" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" 1252 | 1253 | [[package]] 1254 | name = "windows_x86_64_msvc" 1255 | version = "0.48.5" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 1258 | 1259 | [[package]] 1260 | name = "windows_x86_64_msvc" 1261 | version = "0.52.4" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" 1264 | 1265 | [[package]] 1266 | name = "winreg" 1267 | version = "0.50.0" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 1270 | dependencies = [ 1271 | "cfg-if", 1272 | "windows-sys 0.48.0", 1273 | ] 1274 | --------------------------------------------------------------------------------