summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/configmanager.rs36
-rw-r--r--src/main.rs26
-rw-r--r--src/parser.rs66
3 files changed, 84 insertions, 44 deletions
diff --git a/src/configmanager.rs b/src/configmanager.rs
index c0047a5..c005d2c 100644
--- a/src/configmanager.rs
+++ b/src/configmanager.rs
@@ -1,22 +1,25 @@
use std::fs;
use serde::Deserialize;
use dirs::home_dir;
-use std::path::PathBuf;
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct Config {
- pub lat: String,
- pub lon: String,
+ pub lat: f64,
+ pub lon: f64,
pub exclude: String,
- pub appid: String,
- pub lang: String,
- pub units: String,
- pub cache: bool,
- pub rain: String,
- pub sunny: String,
- pub snowy: String,
+ pub appid: String,
+ pub lang: String,
+ pub units: String,
+ pub cache: bool,
+ pub rain: String,
+ pub sunny: String,
+ pub snowy: String,
}
+type BoxedError = Box<dyn std::error::Error + Send + Sync>;
+
+
+
pub fn handle_config(_config: &Config) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
@@ -24,15 +27,20 @@ pub fn handle_config(_config: &Config) -> Result<(), Box<dyn std::error::Error>>
pub fn gen_standard_conf() {
// TODO: Implement
}
-
+
impl Config {
pub fn load() -> Result<Self, Box<dyn std::error::Error>> {
let mut path = home_dir().ok_or("Home directory not found")?;
path.push(".config/WeatherFetch/Config.toml");
- let config_str = fs::read_to_string(path)?;
- let config: Config = toml::from_str(&config_str)?;
+ let config_str = fs::read_to_string(&path)
+ .map_err(|e| format!("Failed to read config: {}", e))?;
+
+ let config: Config = toml::from_str(&config_str)
+ .map_err(|e| format!("Invalid TOML: {}", e))?;
+
Ok(config)
}
}
+
diff --git a/src/main.rs b/src/main.rs
index 9f64ca4..acd3ecb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,13 +4,13 @@ extern crate image;
use clap::{Arg, Command};
use termimage::{Options};
-
mod configmanager;
mod parser;
use crate::configmanager::{Config, handle_config};
-
fn main() -> Result<(), Box<dyn std::error::Error>> {
+
+ let config = Config::load()?;
let matches = Command::new("WeatherFetch")
.version("0.1")
.author("Borisov Alexey <arcanetmodl@gmail.com>")
@@ -24,19 +24,29 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.get_matches();
if matches.contains_id("help") {
- println!("Usage: ...");
+ println!("Usage:");
+ println!("VALUES");
+ println!("--img=, -i= image, takees a path to .jpg/.png");
+ println!("--lat=, -t=, coordinates: takes f64.");
+ println!("--lon=, -n=, coordinates: takes f64");
+ println!("--cfg=, -c=, takes a path to Config.toml");
+ println!("--exclude=, -e=, takes exlude type. See the API docs");
+ println!("FUNCTIONS");
+ println!("--gen-conf, -g, generating standart config");
+ println!("--alerts, -a, show alerts");
+
return Ok(());
}
- if let Some(img_path) = matches.get_one::<String>("image") {
- let _img = Image::from_path(img_path)?;
- }
+ if let Some(img_path) = matches.get_one::<String>("image") {
+ let _img = image::open(img_path)?;
+ }
+
- let config = Config::load()?;
handle_config(&config)?;
- let opts = Options::parse();
+ let _opts = Options::parse(); // Prefix with underscore if not used
/*
if !opts {
opts = configmanager::Config::load();
diff --git a/src/parser.rs b/src/parser.rs
index 5a670b1..e97db13 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -1,8 +1,11 @@
-use reqwest::{Error, Client, get};
+//use clap::error::ErrorKind;
+use reqwest::{Client};
use chrono::{DateTime, Utc, prelude::*};
use serde::{Serialize, Deserialize};
+use once_cell::sync::Lazy;
+use std::error::Error;
-use crate::configmanager;
+use crate::configmanager::Config;
//API answer struct`s
#[derive(Debug, Serialize, Deserialize)]
@@ -12,12 +15,11 @@ pub struct WeatherData {
pub timezone: String,
pub timezone_offset: i32,
pub current: Current,
- pub minutely: Vec<Minutely>,
- pub hourly: Vec<Hourly>,
- pub daily: Vec<Daily>,
- pub alerts: Vec<Alert>,
+ pub minutely: Option<Vec<Minutely>>,
+ pub hourly: Option<Vec<Hourly>>,
+ pub daily: Option<Vec<Daily>>,
+ pub alerts: Option<Vec<Alert>>,
}
-
#[derive(Debug, Serialize, Deserialize)]
pub struct Current {
pub dt: u64,
@@ -121,26 +123,46 @@ pub struct Alert {
pub tags: Vec<String>,
}
+type BoxedError = Box<dyn std::error::Error + Send + Sync>;
+
+const CONF: Lazy<Result<Config, Box<dyn std::error::Error + Send + Sync>>> = Lazy::new(|| {
+ Config::load().map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
+});
+pub fn get_location(coords_args: bool) -> Result<(), BoxedError> {
+ let config = CONF
+ .as_ref()
+ .map_err(|e| Box::<dyn std::error::Error + Send + Sync>::from(e.to_string()))?
+ .clone();
-pub fn get_location(coords_args: bool) -> Result<(), String>{
- //Get the lat and lon for API call
- let conf: Option<configmanager::load()>;
- if conf.lat.is_empty() || conf.lon.is_empty() && !coords_args{
- println!("No coordinates in configuration file or conf not founded.");
- println!("HINT: Try create ~/.config/WeatherFetch/Config.toml");
- println!("HINT: And add `lat(<int>)`, `lon(<int>)`.");
- println!("HINT: To get more info check https://openweathermap.org/api/one-call-3");
-
- Err("No coordinates in config or args.".into())
+ if (config.lat == 0.0 || config.lon == 0.0) && !coords_args {
+ Err("Invalid coordinates in config".into())
} else {
Ok(())
}
-}
-
-
-pub async fn parse_weather(_config: &Config) -> Result<(), reqwest::Error> {
- Ok(())
}
+
+pub async fn parse_weather() -> Result<WeatherData, Box<dyn std::error::Error>> {
+ let config = CONF
+ .as_ref()
+ .map_err(|e| Box::<dyn std::error::Error>::from(e.to_string()))?
+ .clone();
+
+ let client = Client::new();
+ let response = client.get("https://api.openweathermap.org/data/3.0/onecall")
+ .query(&[
+ ("lat", config.lat.to_string()),
+ ("lon", config.lon.to_string()),
+ ("exclude", config.exclude),
+ ("appid", config.appid),
+ ("units", config.units),
+ ("lang", config.lang),
+ ])
+ .send()
+ .await?;
+
+ let weather_data: WeatherData = response.json().await?;
+ Ok(weather_data)
+} \ No newline at end of file