summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main.rs89
1 files changed, 65 insertions, 24 deletions
diff --git a/src/main.rs b/src/main.rs
index dc8ac75..cbaf251 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,21 +1,21 @@
use clap::{Parser, Subcommand};
-
use colored::*;
+use serde::Deserialize;
use traveltext::types::*;
use traveltext::{iceportal::*, travelynx::*};
-#[allow(non_upper_case_globals)]
-const token: &str = "1387-d942ee22-1d34-4dc2-89b6-5e7ef229fb5e";
-#[allow(non_upper_case_globals)]
-const baseurl: &str = "https://travelynx.de";
-
#[derive(Parser)]
struct Cli {
#[clap(subcommand)]
command: Command,
+ /// print requests that couldn't be parsed to help debugging
#[clap(long)]
debug: bool,
+ #[clap(default_value = "https://travelynx.de")]
+ baseurl: String,
+ /// API token to use in requests
+ token: Option<String>,
}
#[derive(Subcommand)]
@@ -39,6 +39,12 @@ enum Command {
ICEPortal,
}
+#[derive(Deserialize)]
+struct Config {
+ token_status: String,
+ token_travel: String,
+}
+
fn main() -> Result<(), ureq::Error> {
let cli = Cli::parse();
@@ -50,22 +56,47 @@ fn main() -> Result<(), ureq::Error> {
"xt".cyan()
);
+ let configpath = {
+ let mut path = dirs::config_dir().unwrap();
+ path.push("traveltext.toml");
+ path
+ };
+
+ let config: Config = match std::fs::read_to_string(&configpath) {
+ Ok(text) => match toml::from_str(&text) {
+ Ok(config) => config,
+ Err(err) => exit_err(
+ &err.to_string(),
+ &format!(
+ "failed parsing config file {}",
+ configpath.to_string_lossy()
+ ),
+ ),
+ },
+ Err(err) => exit_err(
+ &err.to_string(),
+ &format!("failed reading config at: {}", configpath.to_string_lossy()),
+ ),
+ };
+
match cli.command {
Command::Status => {
- let status: Status =
- exiting_get_request(&format!("{}/api/v1/status/{}", baseurl, token), cli.debug);
+ let status: Status = exiting_get_request(
+ &format!("{}/api/v1/status/{}", cli.baseurl, config.token_status),
+ cli.debug,
+ );
println!("{}: {}", traveltext, status);
}
Command::Checkin { from, to, train } => {
let resp: Response = exiting_post_request(
- &format!("{}/api/v1/travel", baseurl),
+ &format!("{}/api/v1/travel", cli.baseurl),
Action::CheckIn {
train,
from_station: from,
to_station: Some(to),
comment: None,
- token: format!("{}", token),
+ token: format!("{}", config.token_travel),
},
cli.debug,
);
@@ -74,9 +105,9 @@ fn main() -> Result<(), ureq::Error> {
}
Command::Undo => {
let resp: Response = exiting_post_request(
- &format!("{}/api/v1/travel", baseurl),
+ &format!("{}/api/v1/travel", cli.baseurl),
Action::Undo {
- token: token.to_owned(),
+ token: config.token_travel.to_owned(),
},
cli.debug,
);
@@ -94,13 +125,13 @@ fn main() -> Result<(), ureq::Error> {
traveltext, train._type, train.no, last_stop
);
let resp: Response = exiting_post_request(
- &format!("{}/api/v1/travel", baseurl),
+ &format!("{}/api/v1/travel", cli.baseurl),
Action::CheckIn {
train,
from_station: last_stop,
to_station: None,
comment: None,
- token: format!("{}", token),
+ token: format!("{}", config.token_travel),
},
cli.debug,
);
@@ -118,20 +149,30 @@ fn main() -> Result<(), ureq::Error> {
Ok(())
}
-fn exiting_get_request<R: serde::de::DeserializeOwned>(uri: &str, debug: bool) -> R {
+fn get_request<R>(uri: &str) -> Result<R, (serde_json::Error, String)>
+where
+ R: serde::de::DeserializeOwned,
+{
let resp: String = ureq::get(uri)
.call()
- .unwrap_or_else(|err| exit_err(&err.to_string()))
+ .unwrap_or_else(|err| exit_err(&err.to_string(), "get request failed"))
.into_string()
- .unwrap_or_else(|err| exit_err(&err.to_string()));
+ .unwrap_or_else(|err| exit_err(&err.to_string(), "get request response failed"));
match serde_json::from_str::<R>(&resp) {
+ Ok(obj) => Ok(obj),
+ Err(err) => Err((err, resp)),
+ }
+}
+
+fn exiting_get_request<R: serde::de::DeserializeOwned>(uri: &str, debug: bool) -> R {
+ match get_request(uri) {
Ok(obj) => obj,
- Err(err) => {
+ Err((err, resp)) => {
if debug {
eprintln!("DEBUG: {}", resp);
}
- exit_err(&err.to_string())
+ exit_err(&err.to_string(), "parsing response failed")
}
}
}
@@ -143,9 +184,9 @@ where
{
let resp: String = ureq::post(uri)
.send_json(payload)
- .unwrap_or_else(|err| exit_err(&err.to_string()))
+ .unwrap_or_else(|err| exit_err(&err.to_string(), "post request failed"))
.into_string()
- .unwrap_or_else(|err| exit_err(&err.to_string()));
+ .unwrap_or_else(|err| exit_err(&err.to_string(), "post request response failed"));
match serde_json::from_str::<R>(&resp) {
Ok(obj) => obj,
@@ -153,12 +194,12 @@ where
if debug {
eprintln!("DEBUG: {}", resp);
}
- exit_err(&err.to_string())
+ exit_err(&err.to_string(), "parsing response failed")
}
}
}
-fn exit_err(msg: &str) -> ! {
- eprintln!("{}", msg);
+fn exit_err(msg: &str, scope: &str) -> ! {
+ eprintln!("{}: {}", scope, msg);
std::process::exit(1)
}