From 344af3ff7c9493b4e2c6eee134b9b341eaabf736 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Tue, 7 Nov 2023 12:58:12 +0100 Subject: add ping support and readable output --- src/requests/start.rs | 113 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 34 deletions(-) (limited to 'src/requests/start.rs') diff --git a/src/requests/start.rs b/src/requests/start.rs index d0c4411..882b154 100644 --- a/src/requests/start.rs +++ b/src/requests/start.rs @@ -1,29 +1,19 @@ -use std::time::Duration; - use futures_util::{StreamExt, SinkExt}; -use indicatif::{ProgressBar, ProgressStyle}; +use indicatif::MultiProgress; use reqwest::StatusCode; use serde::Deserialize; use tokio_tungstenite::{connect_async, tungstenite::Message}; -use crate::{error::CliError, default_headers, ErrorResponse, format_url, Protocols}; +use crate::{error::CliError, default_headers, ErrorResponse, format_url, Protocols, OVERVIEW_STYLE, DEFAULT_STYLE, DONE_STYLE, finish_pb, ERROR_STYLE, OVERVIEW_ERROR, OVERVIEW_DONE, add_pb}; pub async fn start(id: String, ping: bool) -> Result<(), CliError> { - let send_start = ProgressBar::new(1); + let send_start = MultiProgress::new(); + let overview = add_pb(&send_start, OVERVIEW_STYLE, format!("start {}", id)); // TODO: calculate average start-time on server - send_start.set_style( - ProgressStyle::with_template("{spinner:.green} ({elapsed}) {wide_msg}") - .unwrap() - .tick_chars("|/-\\\\") - ); - let url = format_url("start", Protocols::Http)?; - - send_start.set_message(format!("connect to {}", url)); - send_start.enable_steady_tick(Duration::from_millis(125)); - + let connect = add_pb(&send_start, DEFAULT_STYLE, format!("connect to {}", url)); let res = reqwest::Client::new() .post(url) .headers(default_headers()?) @@ -33,7 +23,9 @@ pub async fn start(id: String, ping: bool) -> Result<(), CliError> { .send() .await .map_err(CliError::Reqwest)?; + finish_pb(connect, "connected, got response".to_string(), DONE_STYLE); + let res_pb = add_pb(&send_start, DEFAULT_STYLE, "analyzing response".to_string()); match res.status() { StatusCode::OK => { let body = serde_json::from_str::( @@ -42,11 +34,16 @@ pub async fn start(id: String, ping: bool) -> Result<(), CliError> { .map_err(CliError::Serde)?; if body.boot { - send_start.println("connected, sent start packet"); + finish_pb(res_pb, "sent start packet".to_string(), DONE_STYLE); } if ping { - send_start.println(status_socket(body.uuid, &send_start).await?.to_string()); + let status = status_socket(body.uuid, &send_start).await?; + if status { + finish_pb(overview, format!("successfully started {}", body.id), OVERVIEW_DONE); + } else { + finish_pb(overview, format!("error while starting {}", body.id), OVERVIEW_ERROR); + } } }, _ => { @@ -55,37 +52,63 @@ pub async fn start(id: String, ping: bool) -> Result<(), CliError> { ) .map_err(CliError::Serde)?; - println!("got error: {}", body.error); + res_pb.finish_with_message(format!("✗ got error: {}", body.error)); } } Ok(()) } -async fn status_socket(uuid: String, pb: &ProgressBar) -> Result { - pb.set_message("setup websocket"); - +async fn status_socket(uuid: String, pb: &MultiProgress) -> Result { + // TODO: Remove unwraps + let ws_pb = add_pb(pb, DEFAULT_STYLE, "connect to websocket".to_string()); let (mut ws_stream, _response) = connect_async(format_url("status", Protocols::Websocket)?) .await .expect("Failed to connect"); - pb.println("connected to websocket"); - - pb.set_message("send uuid message"); - ws_stream.send(Message::Text(uuid)).await.unwrap(); - pb.println("sent uuid message"); + finish_pb(ws_pb, "connected to websocket".to_string(), DONE_STYLE); + + ws_stream.send(Message::Text(uuid.clone())).await.unwrap(); - pb.set_message("wait for message"); + let msg_pb = add_pb(pb, DEFAULT_STYLE, "await message".to_string()); let msg = ws_stream.next().await.unwrap(); + finish_pb(msg_pb, "received message".to_string(), DONE_STYLE); - pb.println(format!("msg: {:?}", msg)); - ws_stream.close(None).await.unwrap(); - pb.println("connection closed"); - // TODO: Check for correct UUID and timeout - pb.set_message("verifying message"); - if msg.is_ok() { return Ok(true) } - Ok(false) + let v_pb = add_pb(pb, DEFAULT_STYLE, "verify response".to_string()); + let res = verify_response(msg.unwrap().to_string(), uuid)?; + match res { + Verified::WrongUuid => { + finish_pb(v_pb, "returned wrong uuid".to_string(), ERROR_STYLE); + Ok(false) + }, + Verified::ResponseType(res_type) => { + match res_type { + ResponseType::Start => { + finish_pb(v_pb, "device started".to_string(), DONE_STYLE); + Ok(true) + }, + ResponseType::Timeout => { + finish_pb(v_pb, "ping timed out".to_string(), ERROR_STYLE); + Ok(false) + }, + ResponseType::NotFound => { + finish_pb(v_pb, "unknown uuid".to_string(), ERROR_STYLE); + Ok(false) + }, + } + } + } +} + +fn verify_response(res: String, org_uuid: String) -> Result { + let spl: Vec<&str> = res.split('_').collect(); + let res_type = spl[0]; + let uuid = spl[1]; + + if uuid != org_uuid { return Ok(Verified::WrongUuid) }; + + Ok(Verified::ResponseType(ResponseType::from(res_type)?)) } #[derive(Debug, Deserialize)] @@ -94,3 +117,25 @@ struct StartResponse { id: String, uuid: String, } + +enum Verified { + ResponseType(ResponseType), + WrongUuid +} + +enum ResponseType { + Start, + Timeout, + NotFound, +} + +impl ResponseType { + fn from(value: &str) -> Result { + match value { + "start" => Ok(ResponseType::Start), + "timeout" => Ok(ResponseType::Timeout), + "notfound" => Ok(ResponseType::NotFound), + _ => Err(CliError::WsResponse), + } + } +} -- cgit v1.2.3