From 4f8523ab69c82d461647fdf36618298989ab9008 Mon Sep 17 00:00:00 2001 From: Willem Date: Fri, 11 Apr 2025 15:16:33 -0400 Subject: [PATCH] wip:made score details box output information for highlighted score, worked on outputing score info in log output --- harmony/src/domain/score.rs | 109 ++++++++++++++++++++++++- harmony_tui/src/lib.rs | 11 ++- harmony_tui/src/widget/score.rs | 138 +++----------------------------- 3 files changed, 126 insertions(+), 132 deletions(-) diff --git a/harmony/src/domain/score.rs b/harmony/src/domain/score.rs index dbe7aa5..7f3d410 100644 --- a/harmony/src/domain/score.rs +++ b/harmony/src/domain/score.rs @@ -4,7 +4,7 @@ use serde_value::Value; use super::{interpret::Interpret, topology::Topology}; pub trait Score: - std::fmt::Debug + Send + Sync + CloneBoxScore + SerializeScore + std::fmt::Debug + DisplayValues + Send + Sync + CloneBoxScore + SerializeScore { fn create_interpret(&self) -> Box>; fn name(&self) -> String; @@ -39,3 +39,110 @@ where Box::new(self.clone()) } } + +pub trait DisplayValues { + fn display_value(&self) -> String; + fn print_value(&self, val: &Value, indent: usize) -> String; +} + +impl DisplayValues for S +where + T: Topology, + S: Score + 'static, +{ + fn display_value(&self) -> String { + let mut output = String::new(); + output += &format!("{}\n", &self.name()); + output += &self.print_value(&self.serialize(), 0); + output += "\n"; + output + } + + fn print_value(&self, val: &Value, indent: usize) -> String { + let pad = " ".repeat(indent * 2); + let mut output = String::new(); + + match val { + Value::Bool(b) => output += &format!("{}{}\n", pad, b), + Value::U8(u) => output += &format!("{}{}\n", pad, u), + Value::U16(u) => output += &format!("{}{}\n", pad, u), + Value::U32(u) => output += &format!("{}{}\n", pad, u), + Value::U64(u) => output += &format!("{}{}\n", pad, u), + Value::I8(i) => output += &format!("{}{}\n", pad, i), + Value::I16(i) => output += &format!("{}{}\n", pad, i), + Value::I32(i) => output += &format!("{}{}\n", pad, i), + Value::I64(i) => output += &format!("{}{}\n", pad, i), + Value::F32(f) => output += &format!("{}{}\n", pad, f), + Value::F64(f) => output += &format!("{}{}\n", pad, f), + Value::Char(c) => output += &format!("{}{}\n", pad, c), + Value::String(s) => output += &format!("{}{}\n", pad, s), + Value::Unit => output += &format!("{}\n", pad), + Value::Bytes(bytes) => output += &format!("{}{:?}\n", pad, bytes), + + Value::Option(opt) => match opt { + Some(inner) => { + output += &format!("{}Option:\n", pad); + output += &self.print_value(inner, indent + 1); + } + None => output += &format!("{}None\n", pad), + }, + + Value::Newtype(inner) => { + output += &format!("{}Newtype:\n", pad); + output += &self.print_value(inner, indent + 1); + } + + Value::Seq(seq) => { + if seq.is_empty() { + output += &format!("{}[]\n", pad); + } else { + output += &format!("{}[\n", pad); + for item in seq { + output += &self.print_value(item, indent + 1); + } + output += &format!("{}]\n", pad); + } + } + + Value::Map(map) => { + if map.is_empty() { + output += &format!("{}\n", pad); + } else { + output += &format!( + "{}+--------------------------+----------------------------+\n", + pad + ); + output += &format!("{}| {:<24} | {:<26} |\n", pad, "Key", "Value"); + output += &format!( + "{}+--------------------------+----------------------------+\n", + pad + ); + + for (k, v) in map { + let key_str = match k { + Value::String(s) => s.clone(), + other => format!("{:?}", other), + }; + let val_str = match v { + Value::String(s) => s.clone(), + Value::Bool(b) => b.to_string(), + Value::Option(Some(inner)) => format!("{:?}", inner), + Value::Option(None) => "None".to_string(), + Value::Seq(seq) => format!("{:?}", seq), + _ => format!("{:?}", v), + }; + + output += &format!("{}| {:<24} | {:<26} |\n", pad, key_str, val_str); + } + + output += &format!( + "{}+--------------------------+----------------------------+\n\n", + pad + ); + } + } + } + + output + } +} diff --git a/harmony_tui/src/lib.rs b/harmony_tui/src/lib.rs index 462591d..33de969 100644 --- a/harmony_tui/src/lib.rs +++ b/harmony_tui/src/lib.rs @@ -177,10 +177,13 @@ impl HarmonyTUI { .state(&self.tui_state); frame.render_widget(tui_logger, logger_area); - - let info = self.score.display_value(); - //let info = self.score.display_value(); - let info_block = Block::default().borders(Borders::ALL).title("Scores Info"); + let info_block = Block::default().borders(Borders::ALL).title("Score Details"); + + let scores = &self.score.get_selected_score(); + let mut info = String::new(); + scores.into_iter().for_each(|score| { + info += &score.display_value(); + }); let info_paragraph = Paragraph::new(info) .block(info_block) .wrap(Wrap { trim: true }); diff --git a/harmony_tui/src/widget/score.rs b/harmony_tui/src/widget/score.rs index c4d3d63..beae663 100644 --- a/harmony_tui/src/widget/score.rs +++ b/harmony_tui/src/widget/score.rs @@ -1,6 +1,3 @@ -use ratatui::layout::Constraint; -use serde_value::Value; -use std::collections::BTreeMap; use std::sync::{Arc, RwLock}; use crate::HarmonyTuiEvent; @@ -10,10 +7,8 @@ use log::{info, warn}; use ratatui::{ Frame, layout::Rect, - style::{Modifier, Style, Stylize}, - widgets::{ - Block, Borders, Cell, List, ListItem, ListState, Row, StatefulWidget, Table, Widget, - }, + style::{Style, Stylize}, + widgets::{List, ListItem, ListState, StatefulWidget, Widget}, }; use tokio::sync::mpsc; @@ -57,136 +52,25 @@ impl ScoreListWidget { } pub(crate) fn launch_execution(&mut self) { - let list_read = self.list_state.read().unwrap(); - if let Some(index) = list_read.selected() { - let score = self - .scores - .get(index) - .expect("List state should always match with internal Vec"); - + if let Some(score) = self.get_selected_score() { self.execution = Some(Execution { state: ExecutionState::INITIATED, score: score.clone_box(), }); - //TODO: need to format the output of the score.serialize() - //currently just dumps to MAP() and handle _ - //maybe columns - //https://arcnmx.github.io/serde-value/serde_value/enum.Value.html info!("{:#?}\n\nConfirm Execution (Press y/n)", score); + info!("{:#?}", score.display_value()); } else { warn!("No Score selected, nothing to launch"); } } - //TODO working on match statement to output serialized value - //want to try and build a fn for a few types that are represtendd in DNSscore - //and output them by calling fn display_values in the about fn - // - //currently outputs info about all available scores, not quite - //looking to output info about the selected score and subscores - // - -fn print_value(&self, val: &Value, indent: usize) -> String { - let pad = " ".repeat(indent * 2); - let mut output = String::new(); - - match val { - Value::Bool(b) => output += &format!("{}{}\n", pad, b), - Value::U8(u) => output += &format!("{}{}\n", pad, u), - Value::U16(u) => output += &format!("{}{}\n", pad, u), - Value::U32(u) => output += &format!("{}{}\n", pad, u), - Value::U64(u) => output += &format!("{}{}\n", pad, u), - Value::I8(i) => output += &format!("{}{}\n", pad, i), - Value::I16(i) => output += &format!("{}{}\n", pad, i), - Value::I32(i) => output += &format!("{}{}\n", pad, i), - Value::I64(i) => output += &format!("{}{}\n", pad, i), - Value::F32(f) => output += &format!("{}{}\n", pad, f), - Value::F64(f) => output += &format!("{}{}\n", pad, f), - Value::Char(c) => output += &format!("{}{}\n", pad, c), - Value::String(s) => output += &format!("{}{}\n", pad, s), - Value::Unit => output += &format!("{}\n", pad), - Value::Bytes(bytes) => output += &format!("{}{:?}\n", pad, bytes), - - Value::Option(opt) => match opt { - Some(inner) => { - output += &format!("{}Option:\n", pad); - output += &self.print_value(inner, indent + 1); - } - None => output += &format!("{}None\n", pad), - }, - - Value::Newtype(inner) => { - output += &format!("{}Newtype:\n", pad); - output += &self.print_value(inner, indent + 1); + + pub(crate) fn get_selected_score(&self) -> Option>> { + let list_read = self.list_state.read().unwrap(); + if let Some(index) = list_read.selected() { + self.scores.get(index).map(|s| s.clone_box()) + } else { + None } - - Value::Seq(seq) => { - if seq.is_empty() { - output += &format!("{}[]\n", pad); - } else { - output += &format!("{}[\n", pad); - for item in seq { - output += &self.print_value(item, indent + 1); - } - output += &format!("{}]\n", pad); - } - } - - Value::Map(map) => { - if map.is_empty() { - output += &format!("{}\n", pad); - } else { - output += &format!( - "\n{}+--------------------------+----------------------------+\n", - pad - ); - output += &format!( - "{}| {:<24} | {:<26} |\n", - pad, "Key", "Value" - ); - output += &format!( - "{}+--------------------------+----------------------------+\n", - pad - ); - - for (k, v) in map { - let key_str = match k { - Value::String(s) => s.clone(), - other => format!("{:?}", other), - }; - let val_str = match v { - Value::String(s) => s.clone(), - Value::Bool(b) => b.to_string(), - Value::Option(Some(inner)) => format!("{:?}", inner), - Value::Option(None) => "None".to_string(), - Value::Seq(seq) => format!("{:?}", seq), - _ => format!("{:?}", v), - }; - - output += &format!( - "{}| {:<24} | {:<26} |\n", - pad, key_str, val_str - ); - } - - output += &format!( - "{}+--------------------------+----------------------------+\n\n", - pad - ); - } - } - } - - output -} - - pub(crate) fn display_value(&self) -> String { - let mut output = String::new(); - output += "SCORE DETAILS"; - for score in &self.scores { - let val = score.serialize(); - output += &self.print_value(&val, 0); - } - output } pub(crate) fn scroll_down(&self) {