From 4630e86cdfbff9d78f4c535ce2955cc6eef73fce Mon Sep 17 00:00:00 2001 From: wiru Date: Fri, 31 May 2024 23:55:47 -0300 Subject: [PATCH] wip: fixing bugs and migrating logic --- .../collection_viewer/collection_viewer.rs | 224 +++++++++++------- .../src/pages/collection_viewer/req_uri.rs | 13 +- .../pages/collection_viewer/request_editor.rs | 4 - .../request_editor/editor_tab.rs | 2 - .../collection_viewer/response_viewer.rs | 5 +- .../src/pages/collection_viewer/sidebar.rs | 146 +++++------- hac-core/src/collection/types.rs | 2 +- 7 files changed, 208 insertions(+), 188 deletions(-) delete mode 100644 hac-client/src/pages/collection_viewer/request_editor/editor_tab.rs diff --git a/hac-client/src/pages/collection_viewer/collection_viewer.rs b/hac-client/src/pages/collection_viewer/collection_viewer.rs index 4fbd4b8..0d707b0 100644 --- a/hac-client/src/pages/collection_viewer/collection_viewer.rs +++ b/hac-client/src/pages/collection_viewer/collection_viewer.rs @@ -5,7 +5,7 @@ use hac_core::net::request_manager::Response; use crate::pages::collection_viewer::req_uri::{ReqUri, ReqUriState}; use crate::pages::collection_viewer::request_editor::{ReqEditor, ReqEditorState}; use crate::pages::collection_viewer::response_viewer::ResViewer; -use crate::pages::collection_viewer::sidebar::{Sidebar, SidebarState}; +use crate::pages::collection_viewer::sidebar::Sidebar; use crate::pages::input::Input; use crate::pages::overlay::draw_overlay; use crate::pages::{Component, Eventful}; @@ -25,6 +25,8 @@ use ratatui::widgets::{Block, Borders, Clear, Padding, Paragraph, StatefulWidget use ratatui::Frame; use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}; +use super::sidebar; + #[derive(Debug, PartialEq)] pub struct ExplorerLayout { pub hint_pane: Rect, @@ -46,9 +48,10 @@ pub enum Overlays { enum VisitNode { Next, Prev, + Curr, } -#[derive(Debug, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub enum PaneFocus { Sidebar, ReqUri, @@ -118,6 +121,7 @@ pub enum CreateReqKind { pub struct CollectionViewer<'cv> { response_viewer: ResViewer<'cv>, request_editor: ReqEditor<'cv>, + sidebar: Sidebar<'cv>, colors: &'cv hac_colors::Colors, config: &'cv hac_config::Config, @@ -127,7 +131,7 @@ pub struct CollectionViewer<'cv> { collection_sync_timer: std::time::Instant, selected_request: Option>>, - hovered_request: Option, + hovered_request: Option, dirs_expanded: HashMap, focused_pane: PaneFocus, @@ -168,7 +172,7 @@ impl<'cv> CollectionViewer<'cv> { let hovered_request = collection .requests .as_ref() - .and_then(|requests| requests.first().cloned()); + .and_then(|items| items.first().map(|item| item.get_id())); CollectionViewer { request_editor: ReqEditor::new( @@ -178,6 +182,19 @@ impl<'cv> CollectionViewer<'cv> { layout.req_editor, ), response_viewer: ResViewer::new(colors, None, layout.response_preview), + sidebar: Sidebar::new( + colors, + true, + false, + sidebar::build_lines( + collection.requests.as_ref(), + 0, + &selected_request.as_ref(), + hovered_request.as_ref(), + &mut HashMap::new(), + colors, + ), + ), colors, config, @@ -209,11 +226,7 @@ impl<'cv> CollectionViewer<'cv> { fn handle_sidebar_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result> { if let KeyCode::Esc = key_event.code { self.selected_pane = None; - return Ok(None); - } - - if let (KeyCode::Enter, None) = (key_event.code, self.selected_pane.as_ref()) { - self.selected_pane = Some(PaneFocus::Sidebar); + self.update_selection(); return Ok(None); } @@ -224,7 +237,12 @@ impl<'cv> CollectionViewer<'cv> { { match key_event.code { KeyCode::Enter => { - if let Some(req) = self.hovered_request.as_ref() { + if let Some(id) = self.hovered_request.as_ref() { + let req = get_request_by_id( + self.collection.requests.as_ref().unwrap(), + &self.dirs_expanded, + id, + ); match req { RequestKind::Nested(dir) => { let entry = @@ -232,7 +250,7 @@ impl<'cv> CollectionViewer<'cv> { *entry = !*entry; } RequestKind::Single(req) => { - self.selected_request = Some(Arc::clone(req)); + self.selected_request = Some(Arc::clone(&req)); self.response_viewer.update(None); self.request_editor = ReqEditor::new( self.colors, @@ -242,36 +260,37 @@ impl<'cv> CollectionViewer<'cv> { ); } } + self.build_sidebar_treeview(); } } KeyCode::Char('j') => { - if let Some(ref req) = self.hovered_request { - self.hovered_request = find_next_entry( - self.collection.requests.as_ref().context( - "should never have a selected request without any requests on collection", - )?, - VisitNode::Next, - &self.dirs_expanded, - req, - ) - .or(Some(req.clone())); - } else if let Some(requests) = self.collection.requests.as_ref() { - self.hovered_request = requests.first().cloned(); + if let Some(id) = self.hovered_request.as_mut() { + if let Some(next) = find_next_entry( + self.collection.requests.as_ref().context( + "should never have a selected request without any requests on collection", + )?, + VisitNode::Next, + &self.dirs_expanded, + id, + ) { + *id = next.get_id(); + self.build_sidebar_treeview(); + }; } } KeyCode::Char('k') => { - if let Some(ref id) = self.hovered_request { - self.hovered_request = find_next_entry( - self.collection.requests.as_ref().context( - "should never have a selected request without any requests on collection", - )?, - VisitNode::Prev, - &self.dirs_expanded, - id, - ) - .or(Some(id.clone())); - } else if let Some(requests) = self.collection.requests.as_ref() { - self.hovered_request = requests.first().cloned(); + if let Some(id) = self.hovered_request.as_mut() { + if let Some(next) = find_next_entry( + self.collection.requests.as_ref().expect( + "should never have a selected request without any requests on collection", + ), + VisitNode::Prev, + &self.dirs_expanded, + id, + ) { + *id = next.get_id(); + self.build_sidebar_treeview(); + } } } KeyCode::Char('n') => self.curr_overlay = Overlays::CreateRequest, @@ -282,14 +301,21 @@ impl<'cv> CollectionViewer<'cv> { Ok(None) } + fn build_sidebar_treeview(&mut self) { + self.sidebar.set_lines(sidebar::build_lines( + self.collection.requests.as_ref(), + 0, + &self.selected_request.as_ref(), + self.hovered_request.as_ref(), + &mut HashMap::new(), + self.colors, + )); + } + fn handle_req_uri_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result> { if let KeyCode::Esc = key_event.code { self.selected_pane = None; - return Ok(None); - } - - if let (KeyCode::Enter, None) = (key_event.code, self.selected_pane.as_ref()) { - self.selected_pane = Some(PaneFocus::ReqUri); + self.update_selection(); return Ok(None); } @@ -331,12 +357,9 @@ impl<'cv> CollectionViewer<'cv> { fn handle_editor_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result> { match (key_event.code, &self.selected_pane) { - (KeyCode::Enter, None) => { - self.selected_pane = Some(PaneFocus::Editor); - return Ok(None); - } (KeyCode::Esc, Some(_)) if self.request_editor.mode().eq(&EditorMode::Normal) => { self.selected_pane = None; + self.update_selection(); return Ok(None); } _ => {} @@ -347,21 +370,6 @@ impl<'cv> CollectionViewer<'cv> { self.request_editor.handle_key_event(key_event) } - fn draw_sidebar(&mut self, frame: &mut Frame) { - let mut state = SidebarState::new( - self.collection.requests.as_deref(), - &self.selected_request, - self.hovered_request.as_ref(), - &mut self.dirs_expanded, - self.focused_pane.eq(&PaneFocus::Sidebar), - self.selected_pane - .as_ref() - .is_some_and(|pane| pane.eq(&PaneFocus::Sidebar)), - ); - - Sidebar::new(self.colors).render(self.layout.sidebar, frame.buffer_mut(), &mut state); - } - fn draw_req_uri(&mut self, frame: &mut Frame) { let mut state = ReqUriState::new( &self.selected_request, @@ -405,7 +413,10 @@ impl<'cv> CollectionViewer<'cv> { fn handle_preview_key_event(&mut self, key_event: KeyEvent) -> anyhow::Result> { match key_event.code { - KeyCode::Enter => self.selected_pane = Some(PaneFocus::Preview), + KeyCode::Esc => { + self.selected_pane = None; + self.update_selection(); + } _ => { self.response_viewer.handle_key_event(key_event)?; } @@ -423,9 +434,9 @@ impl<'cv> CollectionViewer<'cv> { } fn draw_sidebar_hint(&self, frame: &mut Frame) { let hint = - "[j/k -> navigate] [enter -> select item] [n -> create request] [? -> help] [ -> quit]" - .fg(self.colors.normal.magenta) - .into_centered_line(); + "[j/k -> navigate] [enter -> select item] [n -> create request] [? -> help] [ -> quit]" + .fg(self.colors.normal.magenta) + .into_centered_line(); frame.render_widget(hint, self.layout.hint_pane); } @@ -737,7 +748,15 @@ impl<'cv> CollectionViewer<'cv> { if let RequestKind::Single(ref req) = new_request { self.selected_request = Some(Arc::clone(req)); - self.hovered_request = Some(new_request.clone()); + self.hovered_request = Some(new_request.get_id()); + self.sidebar.set_lines(sidebar::build_lines( + self.collection.requests.as_ref(), + 0, + &self.selected_request.as_ref(), + self.hovered_request.as_ref(), + &mut HashMap::new(), + self.colors, + )); } self.collection @@ -812,17 +831,14 @@ impl<'cv> CollectionViewer<'cv> { } fn update_selection(&mut self) { - assert!( - self.selected_pane.is_some(), - "update selection can only be called when a pane is selected" - ); - self.response_viewer - .maybe_select(self.selected_pane.as_ref().unwrap()); + .maybe_select(self.selected_pane.as_ref()); + self.sidebar.maybe_select(self.selected_pane.as_ref()); } fn update_focus(&mut self) { self.response_viewer.maybe_focus(&self.focused_pane); + self.sidebar.maybe_focus(&self.focused_pane); } } @@ -840,7 +856,7 @@ impl Component for CollectionViewer<'_> { .draw(frame, self.layout.response_preview)?; self.draw_req_editor(frame); self.draw_req_uri(frame); - self.draw_sidebar(frame); + self.sidebar.draw(frame, self.layout.sidebar)?; match self.focused_pane { PaneFocus::ReqUri => self.draw_req_uri_hint(frame), @@ -932,6 +948,12 @@ impl Eventful for CollectionViewer<'_> { return Ok(Some(Command::Quit)); }; + if let (KeyCode::Enter, None) = (key_event.code, self.selected_pane.as_ref()) { + self.selected_pane = Some(self.focused_pane.clone()); + self.update_selection(); + return Ok(None); + } + if self.curr_overlay.ne(&Overlays::None) { match self.curr_overlay { Overlays::CreateRequest => return self.handle_create_request_key_event(key_event), @@ -1004,16 +1026,20 @@ impl Eventful for CollectionViewer<'_> { if let KeyCode::BackTab = key_event.code { match (&self.focused_pane, &self.selected_pane, key_event.modifiers) { (PaneFocus::Sidebar, None, KeyModifiers::SHIFT) => { - self.focused_pane = PaneFocus::Preview + self.focused_pane = PaneFocus::Preview; + self.update_focus(); } (PaneFocus::ReqUri, None, KeyModifiers::SHIFT) => { - self.focused_pane = PaneFocus::Sidebar + self.focused_pane = PaneFocus::Sidebar; + self.update_focus(); } (PaneFocus::Editor, None, KeyModifiers::SHIFT) => { - self.focused_pane = PaneFocus::ReqUri + self.focused_pane = PaneFocus::ReqUri; + self.update_focus(); } (PaneFocus::Preview, None, KeyModifiers::SHIFT) => { - self.focused_pane = PaneFocus::Editor + self.focused_pane = PaneFocus::Editor; + self.update_focus(); } _ => {} } @@ -1079,10 +1105,10 @@ fn traverse( visit: &VisitNode, dirs_expanded: &HashMap, current: &RequestKind, - needle: &RequestKind, + needle: &str, path: &mut Vec, ) -> bool { - let node_match = current.get_id().eq(&needle.get_id()); + let node_match = current.get_id().eq(needle); match (&visit, node_match, &found) { // We are looking for the next item and we already found the current one (needle), so the @@ -1100,6 +1126,11 @@ fn traverse( // We are looking for the next and just found the current one, so we set the flag to // true in order to know when to return the next. (VisitNode::Next, true, false) => *found = true, + (VisitNode::Curr, true, _) => { + path.push(current.clone()); + *found = true; + return *found; + } _ => {} } @@ -1123,11 +1154,36 @@ fn traverse( false } +fn get_request_by_id( + tree: &[RequestKind], + dirs_expanded: &HashMap, + id: &str, +) -> RequestKind { + let mut found = false; + let mut path = vec![]; + + for node in tree { + if traverse( + &mut found, + &VisitNode::Curr, + dirs_expanded, + node, + id, + &mut path, + ) { + break; + } + } + + path.pop() + .expect("attempting to find an unexisting request") +} + fn find_next_entry( tree: &[RequestKind], visit: VisitNode, dirs_expanded: &HashMap, - needle: &RequestKind, + needle: &str, ) -> Option { let mut found = false; let mut path = vec![]; @@ -1226,7 +1282,7 @@ mod tests { let needle = create_nested(); let expected = create_root_two(); - let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle); + let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle.get_id()); assert!(next.is_some()); assert_eq!(next.unwrap().get_id(), expected.get_id()); @@ -1240,7 +1296,7 @@ mod tests { let needle = create_nested(); let expected = create_child_one(); - let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle); + let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle.get_id()); assert!(next.is_some()); assert_eq!(next.unwrap().get_id(), expected.get_id()); @@ -1253,7 +1309,7 @@ mod tests { dirs_expanded.insert(create_dir().id, true); let needle = create_not_used(); - let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle); + let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle.get_id()); assert!(next.is_none()); } @@ -1266,7 +1322,7 @@ mod tests { let needle = create_child_one(); let expected = create_nested(); - let next = find_next_entry(&tree, VisitNode::Prev, &dirs_expanded, &needle); + let next = find_next_entry(&tree, VisitNode::Prev, &dirs_expanded, &needle.get_id()); assert!(next.is_some()); assert_eq!(next.unwrap().get_id(), expected.get_id()); @@ -1280,7 +1336,7 @@ mod tests { let needle = create_root_two(); let expected = create_child_two(); - let next = find_next_entry(&tree, VisitNode::Prev, &dirs_expanded, &needle); + let next = find_next_entry(&tree, VisitNode::Prev, &dirs_expanded, &needle.get_id()); assert!(next.is_some()); assert_eq!(next.unwrap().get_id(), expected.get_id()); @@ -1292,7 +1348,7 @@ mod tests { let dirs_expanded = HashMap::new(); let needle = create_root_two(); - let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle); + let next = find_next_entry(&tree, VisitNode::Next, &dirs_expanded, &needle.get_id()); assert!(next.is_none()); } diff --git a/hac-client/src/pages/collection_viewer/req_uri.rs b/hac-client/src/pages/collection_viewer/req_uri.rs index d67ed2a..60a8606 100644 --- a/hac-client/src/pages/collection_viewer/req_uri.rs +++ b/hac-client/src/pages/collection_viewer/req_uri.rs @@ -1,12 +1,11 @@ +use hac_core::collection::types::Request; + use std::sync::{Arc, RwLock}; -use hac_core::collection::types::Request; -use ratatui::{ - buffer::Buffer, - layout::Rect, - style::{Style, Stylize}, - widgets::{Block, Borders, Paragraph, StatefulWidget, Widget}, -}; +use ratatui::buffer::Buffer; +use ratatui::layout::Rect; +use ratatui::style::{Style, Stylize}; +use ratatui::widgets::{Block, Borders, Paragraph, StatefulWidget, Widget}; #[derive(Debug)] pub struct ReqUriState<'a> { diff --git a/hac-client/src/pages/collection_viewer/request_editor.rs b/hac-client/src/pages/collection_viewer/request_editor.rs index 26982cd..563b6a2 100644 --- a/hac-client/src/pages/collection_viewer/request_editor.rs +++ b/hac-client/src/pages/collection_viewer/request_editor.rs @@ -1,5 +1,3 @@ -mod editor_tab; - use crate::{pages::Eventful, utils::build_syntax_highlighted_lines}; use hac_config::{Action, EditorMode, KeyAction}; @@ -79,7 +77,6 @@ pub struct ReqEditor<'re> { col_scroll: usize, layout: ReqEditorLayout, config: &'re hac_config::Config, - request: Option>>, curr_tab: ReqEditorTabs, @@ -131,7 +128,6 @@ impl<'re> ReqEditor<'re> { .unwrap_or(false) .then_some(ReqEditorTabs::Headers) .unwrap_or_default(), - request, keymap_buffer: None, } } diff --git a/hac-client/src/pages/collection_viewer/request_editor/editor_tab.rs b/hac-client/src/pages/collection_viewer/request_editor/editor_tab.rs deleted file mode 100644 index 139597f..0000000 --- a/hac-client/src/pages/collection_viewer/request_editor/editor_tab.rs +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/hac-client/src/pages/collection_viewer/response_viewer.rs b/hac-client/src/pages/collection_viewer/response_viewer.rs index a68367d..d30ea9c 100644 --- a/hac-client/src/pages/collection_viewer/response_viewer.rs +++ b/hac-client/src/pages/collection_viewer/response_viewer.rs @@ -558,9 +558,8 @@ impl<'a> ResViewer<'a> { } } - pub fn maybe_select(&mut self, selected_pane: &PaneFocus) { - self.is_selected = selected_pane.eq(&PaneFocus::Preview); - self.is_focused = selected_pane.eq(&PaneFocus::Preview); + pub fn maybe_select(&mut self, selected_pane: Option<&PaneFocus>) { + self.is_selected = selected_pane.is_some_and(|pane| pane.eq(&PaneFocus::Preview)); } pub fn maybe_focus(&mut self, focused_pane: &PaneFocus) { diff --git a/hac-client/src/pages/collection_viewer/sidebar.rs b/hac-client/src/pages/collection_viewer/sidebar.rs index 75e51f4..139cc20 100644 --- a/hac-client/src/pages/collection_viewer/sidebar.rs +++ b/hac-client/src/pages/collection_viewer/sidebar.rs @@ -1,83 +1,59 @@ use hac_core::collection::types::{Request, RequestKind, RequestMethod}; -use ratatui::{ - buffer::Buffer, - layout::Rect, - style::{Style, Styled, Stylize}, - text::{Line, Span}, - widgets::{Block, Borders, Paragraph, StatefulWidget, Widget}, -}; -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; - -pub struct SidebarState<'a> { - requests: Option<&'a [RequestKind]>, - selected_request: &'a Option>>, - hovered_requet: Option<&'a RequestKind>, - dirs_expanded: &'a mut HashMap, + +use crate::pages::Component; + +use std::collections::HashMap; +use std::sync::{Arc, RwLock}; + +use ratatui::layout::Rect; +use ratatui::style::{Style, Styled, Stylize}; +use ratatui::text::{Line, Span}; +use ratatui::widgets::{Block, Borders, Paragraph}; +use ratatui::Frame; + +use super::collection_viewer::PaneFocus; + +#[derive(Debug)] +pub struct Sidebar<'s> { + colors: &'s hac_colors::Colors, is_focused: bool, is_selected: bool, + lines: Vec>, } -impl<'a> SidebarState<'a> { +impl<'s> Sidebar<'s> { pub fn new( - requests: Option<&'a [RequestKind]>, - selected_request: &'a Option>>, - hovered_requet: Option<&'a RequestKind>, - dirs_expanded: &'a mut HashMap, + colors: &'s hac_colors::Colors, is_focused: bool, is_selected: bool, + lines: Vec>, ) -> Self { - SidebarState { - requests, - selected_request, - hovered_requet, - dirs_expanded, + Self { + colors, is_focused, is_selected, + lines, } } -} -#[derive(Debug, Clone)] -pub struct RenderLine { - pub _level: usize, - pub _name: String, - pub line: Paragraph<'static>, -} + pub fn set_lines(&mut self, lines: Vec>) { + self.lines = lines; + } -pub struct Sidebar<'a> { - colors: &'a hac_colors::Colors, -} + pub fn maybe_select(&mut self, selected_pane: Option<&PaneFocus>) { + self.is_selected = selected_pane.is_some_and(|pane| pane.eq(&PaneFocus::Sidebar)); + } -impl<'a> Sidebar<'a> { - pub fn new(colors: &'a hac_colors::Colors) -> Self { - Self { colors } + pub fn maybe_focus(&mut self, focused_pane: &PaneFocus) { + self.is_focused = focused_pane.eq(&PaneFocus::Sidebar); } } -impl<'a> StatefulWidget for Sidebar<'a> { - type State = SidebarState<'a>; - - fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) { - let lines = build_lines( - state.requests, - 0, - state.selected_request, - state.hovered_requet, - state.dirs_expanded, - self.colors, - ); - - let mut requests_size = Rect::new(area.x + 1, area.y, area.width.saturating_sub(2), 1); +impl<'s> Component for Sidebar<'s> { + fn draw(&mut self, frame: &mut Frame, size: Rect) -> anyhow::Result<()> { + let mut requests_size = Rect::new(size.x + 1, size.y, size.width.saturating_sub(2), 1); - let requests = lines - .iter() - .map(|l| l.line.clone()) - .collect::>(); - - let block_border = match (state.is_focused, state.is_selected) { + let block_border = match (self.is_focused, self.is_selected) { (true, false) => Style::default().fg(self.colors.bright.blue), (true, true) => Style::default().fg(self.colors.normal.red), (false, _) => Style::default().fg(self.colors.bright.black), @@ -91,29 +67,33 @@ impl<'a> StatefulWidget for Sidebar<'a> { ]) .border_style(block_border); - block.render(area, buf); + frame.render_widget(block, size); - requests.iter().for_each(|req| { + self.lines.clone().into_iter().for_each(|req| { requests_size.y += 1; - req.render(requests_size, buf); + frame.render_widget(req, requests_size); }); + + Ok(()) } + + fn resize(&mut self, _new_size: Rect) {} } -fn build_lines( - requests: Option<&[RequestKind]>, +pub fn build_lines( + requests: Option<&Vec>, level: usize, - selected_request: &Option>>, - hovered_request: Option<&RequestKind>, + selected_request: &Option<&Arc>>, + hovered_request: Option<&String>, dirs_expanded: &mut HashMap, colors: &hac_colors::Colors, -) -> Vec { +) -> Vec> { requests - .unwrap_or_default() + .unwrap_or(&vec![]) .iter() .flat_map(|item| match item { RequestKind::Nested(dir) => { - let is_hovered = hovered_request.is_some_and(|req| req.get_id().eq(&item.get_id())); + let is_hovered = hovered_request.is_some_and(|id| id.eq(&item.get_id())); let is_expanded = dirs_expanded.entry(dir.id.to_string()).or_insert(false); let dir_style = match is_hovered { @@ -126,17 +106,13 @@ fn build_lines( let gap = " ".repeat(level * 2); let chevron = if *is_expanded { "v" } else { ">" }; - let line = vec![RenderLine { - _level: level, - _name: dir.name.clone(), - line: Paragraph::new(format!( - "{}{} {}/", - gap, - chevron, - dir.name.to_lowercase().replace(' ', "-") - )) - .set_style(dir_style), - }]; + let line = vec![Paragraph::new(format!( + "{}{} {}/", + gap, + chevron, + dir.name.to_lowercase().replace(' ', "-") + )) + .set_style(dir_style)]; let nested_lines = if *is_expanded { build_lines( @@ -157,7 +133,7 @@ fn build_lines( let is_selected = selected_request.as_ref().is_some_and(|selected| { selected.read().unwrap().id.eq(&req.read().unwrap().id) }); - let is_hovered = hovered_request.is_some_and(|req| req.get_id().eq(&item.get_id())); + let is_hovered = hovered_request.is_some_and(|id| id.eq(&item.get_id())); let req_style = match (is_selected, is_hovered) { (true, true) => Style::default() @@ -179,11 +155,7 @@ fn build_lines( ] .into(); - vec![RenderLine { - _level: level, - _name: req.read().unwrap().name.clone(), - line: Paragraph::new(line).set_style(req_style), - }] + vec![Paragraph::new(line).set_style(req_style)] } }) .collect() diff --git a/hac-core/src/collection/types.rs b/hac-core/src/collection/types.rs index 7a215f9..245ef05 100644 --- a/hac-core/src/collection/types.rs +++ b/hac-core/src/collection/types.rs @@ -106,7 +106,7 @@ impl Hash for Request { } } -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Default, Serialize, Deserialize, Clone)] pub struct Directory { pub id: String, pub name: String,