summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs111
1 files changed, 61 insertions, 50 deletions
diff --git a/src/main.rs b/src/main.rs
index afe6fac..5a0931d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,21 +1,24 @@
1use std::{fmt::Display, time::Duration}; 1use std::{fmt::Display, time::Duration};
2 2
3use clap::{Parser, Command, CommandFactory, Subcommand}; 3use crate::config::Config;
4use clap_complete::{generate, Shell, Generator}; 4use clap::{Command, CommandFactory, Parser, Subcommand};
5use config::SETTINGS; 5use clap_complete::{generate, Generator, Shell};
6use error::CliError; 6use error::Error;
7use indicatif::{ProgressBar, ProgressStyle, MultiProgress}; 7use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
8use requests::{start::start, device}; 8use requests::{device, start::start};
9use reqwest::header::{HeaderMap, HeaderValue}; 9use reqwest::{
10 header::{HeaderMap, HeaderValue},
11 Response,
12};
10use serde::Deserialize; 13use serde::Deserialize;
11 14
12mod config; 15mod config;
13mod error; 16mod error;
14mod requests; 17mod requests;
15 18
16static OVERVIEW_STYLE: &str = "{spinner:.green} ({elapsed}{wide_msg}"; 19static OVERVIEW_STYLE: &str = "{spinner:.green} ({elapsed_precise}{wide_msg}";
17static OVERVIEW_ERROR: &str = "✗ ({elapsed}) {wide_msg}"; 20static OVERVIEW_ERROR: &str = "✗ ({elapsed_precise}) {wide_msg}";
18static OVERVIEW_DONE: &str = "✓ ({elapsed}) {wide_msg}"; 21static OVERVIEW_DONE: &str = "✓ ({elapsed_precise}) {wide_msg}";
19static DEFAULT_STYLE: &str = " {spinner:.green} {wide_msg}"; 22static DEFAULT_STYLE: &str = " {spinner:.green} {wide_msg}";
20static DONE_STYLE: &str = " ✓ {wide_msg}"; 23static DONE_STYLE: &str = " ✓ {wide_msg}";
21static ERROR_STYLE: &str = " ✗ {wide_msg}"; 24static ERROR_STYLE: &str = " ✗ {wide_msg}";
@@ -35,7 +38,7 @@ enum Commands {
35 /// id of the device 38 /// id of the device
36 id: String, 39 id: String,
37 #[arg(short, long)] 40 #[arg(short, long)]
38 ping: Option<bool> 41 ping: Option<bool>,
39 }, 42 },
40 Device { 43 Device {
41 #[command(subcommand)] 44 #[command(subcommand)]
@@ -52,7 +55,7 @@ enum DeviceCmd {
52 id: String, 55 id: String,
53 mac: String, 56 mac: String,
54 broadcast_addr: String, 57 broadcast_addr: String,
55 ip: String 58 ip: String,
56 }, 59 },
57 Get { 60 Get {
58 id: String, 61 id: String,
@@ -61,35 +64,45 @@ enum DeviceCmd {
61 id: String, 64 id: String,
62 mac: String, 65 mac: String,
63 broadcast_addr: String, 66 broadcast_addr: String,
64 ip: String 67 ip: String,
65 }, 68 },
66} 69}
67 70
68#[tokio::main] 71#[tokio::main]
69async fn main() -> Result<(), CliError> { 72async fn main() -> Result<(), anyhow::Error> {
73 let config = Config::load()?;
74
70 let cli = Args::parse(); 75 let cli = Args::parse();
71 76
72 match cli.commands { 77 match cli.commands {
73 Commands::Start { id, ping } => { 78 Commands::Start { id, ping } => {
74 start(id, ping.unwrap_or(true)).await?; 79 start(&config, id, ping.unwrap_or(true)).await?;
75 }, 80 }
76 Commands::Device { devicecmd } => { 81 Commands::Device { devicecmd } => match devicecmd {
77 match devicecmd { 82 DeviceCmd::Add {
78 DeviceCmd::Add { id, mac, broadcast_addr, ip } => { 83 id,
79 device::put(id, mac, broadcast_addr, ip).await?; 84 mac,
80 }, 85 broadcast_addr,
81 DeviceCmd::Get { id } => { 86 ip,
82 device::get(id).await?; 87 } => {
83 }, 88 device::put(&config, id, mac, broadcast_addr, ip).await?;
84 DeviceCmd::Edit { id, mac, broadcast_addr, ip } => { 89 }
85 device::post(id, mac, broadcast_addr, ip).await?; 90 DeviceCmd::Get { id } => {
86 }, 91 device::get(&config, id).await?;
92 }
93 DeviceCmd::Edit {
94 id,
95 mac,
96 broadcast_addr,
97 ip,
98 } => {
99 device::post(&config, id, mac, broadcast_addr, ip).await?;
87 } 100 }
88 }, 101 },
89 Commands::CliGen { id } => { 102 Commands::CliGen { id } => {
90 eprintln!("Generating completion file for {id:?}..."); 103 eprintln!("Generating completion file for {id:?}...");
91 let mut cmd = Args::command(); 104 let mut cmd = Args::command();
92 print_completions(id, &mut cmd) 105 print_completions(id, &mut cmd);
93 } 106 }
94 } 107 }
95 108
@@ -100,29 +113,28 @@ fn print_completions<G: Generator>(gen: G, cmd: &mut Command) {
100 generate(gen, cmd, cmd.get_name().to_string(), &mut std::io::stdout()); 113 generate(gen, cmd, cmd.get_name().to_string(), &mut std::io::stdout());
101} 114}
102 115
103fn default_headers() -> Result<HeaderMap, CliError> { 116fn default_headers(config: &Config) -> Result<HeaderMap, Error> {
104 let mut map = HeaderMap::new(); 117 let mut map = HeaderMap::new();
105 map.append("Accept-Content", HeaderValue::from_str("application/json").unwrap()); 118 map.append("Accept-Content", HeaderValue::from_str("application/json")?);
106 map.append("Content-Type", HeaderValue::from_str("application/json").unwrap()); 119 map.append("Content-Type", HeaderValue::from_str("application/json")?);
107 map.append( 120 map.append("Authorization", HeaderValue::from_str(&config.apikey)?);
108 "Authorization",
109 HeaderValue::from_str(
110 SETTINGS.get_string("key")
111 .map_err(CliError::Config)?
112 .as_str()
113 ).unwrap()
114 );
115 121
116 Ok(map) 122 Ok(map)
117} 123}
118 124
119fn format_url(path: &str, protocol: Protocols) -> Result<String, CliError> { 125fn format_url(config: &Config, path: &str, protocol: &Protocols) -> String {
120 Ok(format!( 126 format!("{}://{}/{}", protocol, config.server, path)
121 "{}://{}/{}", 127}
122 protocol, 128
123 SETTINGS.get_string("server").map_err(CliError::Config)?, 129async fn check_success(res: Response) -> Result<String, Error> {
124 path 130 let status = res.status();
125 )) 131 if status.is_success() {
132 Ok(res.text().await?)
133 } else if status.as_u16() == 401 {
134 Err(Error::Authorization)
135 } else {
136 Err(Error::HttpStatus(status.as_u16()))
137 }
126} 138}
127 139
128fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar { 140fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar {
@@ -134,10 +146,9 @@ fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar {
134 pb 146 pb
135} 147}
136 148
137fn finish_pb(pb: ProgressBar, message: String, template: &str) { 149fn finish_pb(pb: &ProgressBar, message: String, template: &str) {
138 pb.set_style(ProgressStyle::with_template(template).unwrap()); 150 pb.set_style(ProgressStyle::with_template(template).unwrap());
139 pb.finish_with_message(message); 151 pb.finish_with_message(message);
140
141} 152}
142 153
143enum Protocols { 154enum Protocols {
@@ -149,12 +160,12 @@ impl Display for Protocols {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 match self { 161 match self {
151 Self::Http => f.write_str("http"), 162 Self::Http => f.write_str("http"),
152 Self::Websocket => f.write_str("ws") 163 Self::Websocket => f.write_str("ws"),
153 } 164 }
154 } 165 }
155} 166}
156 167
157#[derive(Debug, Deserialize)] 168#[derive(Debug, Deserialize)]
158struct ErrorResponse { 169struct ErrorResponse {
159 error: String 170 error: String,
160} 171}