diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 111 |
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 @@ | |||
1 | use std::{fmt::Display, time::Duration}; | 1 | use std::{fmt::Display, time::Duration}; |
2 | 2 | ||
3 | use clap::{Parser, Command, CommandFactory, Subcommand}; | 3 | use crate::config::Config; |
4 | use clap_complete::{generate, Shell, Generator}; | 4 | use clap::{Command, CommandFactory, Parser, Subcommand}; |
5 | use config::SETTINGS; | 5 | use clap_complete::{generate, Generator, Shell}; |
6 | use error::CliError; | 6 | use error::Error; |
7 | use indicatif::{ProgressBar, ProgressStyle, MultiProgress}; | 7 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; |
8 | use requests::{start::start, device}; | 8 | use requests::{device, start::start}; |
9 | use reqwest::header::{HeaderMap, HeaderValue}; | 9 | use reqwest::{ |
10 | header::{HeaderMap, HeaderValue}, | ||
11 | Response, | ||
12 | }; | ||
10 | use serde::Deserialize; | 13 | use serde::Deserialize; |
11 | 14 | ||
12 | mod config; | 15 | mod config; |
13 | mod error; | 16 | mod error; |
14 | mod requests; | 17 | mod requests; |
15 | 18 | ||
16 | static OVERVIEW_STYLE: &str = "{spinner:.green} ({elapsed}{wide_msg}"; | 19 | static OVERVIEW_STYLE: &str = "{spinner:.green} ({elapsed_precise}{wide_msg}"; |
17 | static OVERVIEW_ERROR: &str = "✗ ({elapsed}) {wide_msg}"; | 20 | static OVERVIEW_ERROR: &str = "✗ ({elapsed_precise}) {wide_msg}"; |
18 | static OVERVIEW_DONE: &str = "✓ ({elapsed}) {wide_msg}"; | 21 | static OVERVIEW_DONE: &str = "✓ ({elapsed_precise}) {wide_msg}"; |
19 | static DEFAULT_STYLE: &str = " {spinner:.green} {wide_msg}"; | 22 | static DEFAULT_STYLE: &str = " {spinner:.green} {wide_msg}"; |
20 | static DONE_STYLE: &str = " ✓ {wide_msg}"; | 23 | static DONE_STYLE: &str = " ✓ {wide_msg}"; |
21 | static ERROR_STYLE: &str = " ✗ {wide_msg}"; | 24 | static 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] |
69 | async fn main() -> Result<(), CliError> { | 72 | async 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 | ||
103 | fn default_headers() -> Result<HeaderMap, CliError> { | 116 | fn 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 | ||
119 | fn format_url(path: &str, protocol: Protocols) -> Result<String, CliError> { | 125 | fn 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)?, | 129 | async 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 | ||
128 | fn add_pb(mp: &MultiProgress, template: &str, message: String) -> ProgressBar { | 140 | fn 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 | ||
137 | fn finish_pb(pb: ProgressBar, message: String, template: &str) { | 149 | fn 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 | ||
143 | enum Protocols { | 154 | enum 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)] |
158 | struct ErrorResponse { | 169 | struct ErrorResponse { |
159 | error: String | 170 | error: String, |
160 | } | 171 | } |