diff --git a/src/flatten.rs b/src/flatten.rs index 37e861e..905ec18 100644 --- a/src/flatten.rs +++ b/src/flatten.rs @@ -1,13 +1,13 @@ use std::collections::HashSet; -use crate::item::Item; +use crate::tree_item::TreeItem; -/// A flattened item of all visible [`TreeItem`s](Item). +/// A flattened item of all visible [`TreeItem`]s. /// /// Generated via [`TreeState::flatten`](crate::TreeState::flatten). pub struct Flattened<'a, Identifier> { pub identifier: Vec, - pub item: &'a Item<'a, Identifier>, + pub item: &'a TreeItem<'a, Identifier>, } impl<'a, Identifier> Flattened<'a, Identifier> { @@ -17,11 +17,11 @@ impl<'a, Identifier> Flattened<'a, Identifier> { } } -/// Get a flat list of all visible [`TreeItem`s](TreeItem). +/// Get a flat list of all visible [`TreeItem`]s. #[must_use] pub fn flatten<'a, Identifier>( opened: &HashSet>, - items: &'a [Item<'a, Identifier>], + items: &'a [TreeItem<'a, Identifier>], ) -> Vec> where Identifier: Clone + PartialEq + Eq + core::hash::Hash, @@ -32,7 +32,7 @@ where #[must_use] fn internal<'a, Identifier>( opened: &HashSet>, - items: &'a [Item<'a, Identifier>], + items: &'a [TreeItem<'a, Identifier>], current: &[Identifier], ) -> Vec> where @@ -57,25 +57,28 @@ where } #[cfg(test)] -fn get_example_tree_items() -> Vec> { +fn get_example_tree_items() -> Vec> { vec![ - Item::new_leaf("a", "Alfa"), - Item::new( + TreeItem::new_leaf("a", "Alfa"), + TreeItem::new( "b", "Bravo", vec![ - Item::new_leaf("c", "Charlie"), - Item::new( + TreeItem::new_leaf("c", "Charlie"), + TreeItem::new( "d", "Delta", - vec![Item::new_leaf("e", "Echo"), Item::new_leaf("f", "Foxtrot")], + vec![ + TreeItem::new_leaf("e", "Echo"), + TreeItem::new_leaf("f", "Foxtrot"), + ], ) .expect("all item identifiers are unique"), - Item::new_leaf("g", "Golf"), + TreeItem::new_leaf("g", "Golf"), ], ) .expect("all item identifiers are unique"), - Item::new_leaf("h", "Hotel"), + TreeItem::new_leaf("h", "Hotel"), ] } diff --git a/src/lib.rs b/src/lib.rs index 4b65380..f627084 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ /*! Widget built to show Tree Data structures. -Tree widget [`Tree`] is generated with [`TreeItem`s](TreeItem) (which itself can contain [`TreeItem`] children to form the tree structure). +Tree widget [`Tree`] is generated with [`TreeItem`]s (which itself can contain [`TreeItem`] children to form the tree structure). The user interaction state (like the current selection) is stored in the [`TreeState`]. */ @@ -17,16 +17,16 @@ use ratatui::widgets::{Block, Scrollbar, ScrollbarState, StatefulWidget, Widget} use unicode_width::UnicodeWidthStr; mod flatten; -mod item; -mod state; +mod tree_item; +mod tree_state; pub use crate::flatten::Flattened; -pub use crate::item::Item as TreeItem; -pub use crate::state::State as TreeState; +pub use crate::tree_item::TreeItem; +pub use crate::tree_state::TreeState; /// A `Tree` which can be rendered. /// -/// The generic argument `Identifier` is used to keep the state like the currently selected or opened [`TreeItem`s](TreeItem) in the [`TreeState`]. +/// The generic argument `Identifier` is used to keep the state like the currently selected or opened [`TreeItem`]s in the [`TreeState`]. /// For more information see [`TreeItem`]. /// /// # Example diff --git a/src/item.rs b/src/tree_item.rs similarity index 84% rename from src/item.rs rename to src/tree_item.rs index aad3022..8ccb6ed 100644 --- a/src/item.rs +++ b/src/tree_item.rs @@ -9,9 +9,9 @@ use ratatui::text::Text; /// /// # Identifier /// -/// The generic argument `Identifier` is used to keep the state like the currently selected or opened [`TreeItem`s](Item) in the [`TreeState`](crate::TreeState). +/// The generic argument `Identifier` is used to keep the state like the currently selected or opened [`TreeItem`]s in the [`TreeState`](crate::TreeState). /// -/// It needs to be unique among its siblings but can be used again on parent or child [`TreeItem`s](Item). +/// It needs to be unique among its siblings but can be used again on parent or child [`TreeItem`]s. /// A common example would be a filename which has to be unique in its directory while it can exist in another. /// /// The `text` can be different from its `identifier`. @@ -19,7 +19,7 @@ use ratatui::text::Text; /// The filename `main.rs` is the identifier while its shown as `main`. /// Two files `main.rs` and `main.toml` can exist in the same directory and can both be displayed as `main` but their identifier is different. /// -/// Just like every file in a file system can be uniquely identified with its file and directory names each [`TreeItem`](Item) in a [`Tree`](crate::Tree) can be with these identifiers. +/// Just like every file in a file system can be uniquely identified with its file and directory names each [`TreeItem`] in a [`Tree`](crate::Tree) can be with these identifiers. /// As an example the following two identifiers describe the main file in a Rust cargo project: `vec!["src", "main.rs"]`. /// /// The identifier does not need to be a `String` and is therefore generic. @@ -35,14 +35,14 @@ use ratatui::text::Text; /// # Ok::<(), std::io::Error>(()) /// ``` #[derive(Debug, Clone)] -pub struct Item<'a, Identifier> { +pub struct TreeItem<'a, Identifier> { pub(super) identifier: Identifier, pub(super) text: Text<'a>, pub(super) style: Style, - pub(super) children: Vec>, + pub(super) children: Vec>, } -impl<'a, Identifier> Item<'a, Identifier> +impl<'a, Identifier> TreeItem<'a, Identifier> where Identifier: Clone + PartialEq + Eq + core::hash::Hash, { @@ -68,7 +68,7 @@ where pub fn new( identifier: Identifier, text: T, - children: Vec>, + children: Vec>, ) -> std::io::Result where T: Into>, @@ -93,7 +93,7 @@ where } #[must_use] - pub fn children(&self) -> &[Item] { + pub fn children(&self) -> &[TreeItem] { &self.children } @@ -127,7 +127,7 @@ where /// # Errors /// /// Errors when the `identifier` of the `child` already exists in the children. - pub fn add_child(&mut self, child: Item<'a, Identifier>) -> std::io::Result<()> { + pub fn add_child(&mut self, child: TreeItem<'a, Identifier>) -> std::io::Result<()> { let existing = self .children .iter() @@ -148,16 +148,16 @@ where #[test] #[should_panic = "duplicate identifiers"] fn tree_item_new_errors_with_duplicate_identifiers() { - let item = Item::new_leaf("same", "text"); + let item = TreeItem::new_leaf("same", "text"); let another = item.clone(); - Item::new("root", "Root", vec![item, another]).unwrap(); + TreeItem::new("root", "Root", vec![item, another]).unwrap(); } #[test] #[should_panic = "identifier already exists"] fn tree_item_add_child_errors_with_duplicate_identifiers() { - let item = Item::new_leaf("same", "text"); + let item = TreeItem::new_leaf("same", "text"); let another = item.clone(); - let mut root = Item::new("root", "Root", vec![item]).unwrap(); + let mut root = TreeItem::new("root", "Root", vec![item]).unwrap(); root.add_child(another).unwrap(); } diff --git a/src/state.rs b/src/tree_state.rs similarity index 88% rename from src/state.rs rename to src/tree_state.rs index 347af9d..a3a4086 100644 --- a/src/state.rs +++ b/src/tree_state.rs @@ -1,12 +1,12 @@ use std::collections::HashSet; use crate::flatten::{flatten, Flattened}; -use crate::item::Item; +use crate::tree_item::TreeItem; /// Keeps the state of what is currently selected and what was opened in a [`Tree`](crate::Tree). /// -/// The generic argument `Identifier` is used to keep the state like the currently selected or opened [`TreeItem`s](Item) in the [`TreeState`](State). -/// For more information see [`TreeItem`](Item). +/// The generic argument `Identifier` is used to keep the state like the currently selected or opened [`TreeItem`]s in the [`TreeState`]. +/// For more information see [`TreeItem`]. /// /// # Example /// @@ -17,14 +17,14 @@ use crate::item::Item; /// let mut state = TreeState::::default(); /// ``` #[derive(Debug, Default, Clone)] -pub struct State { +pub struct TreeState { pub(super) offset: usize, pub(super) opened: HashSet>, pub(super) selected: Vec, pub(super) ensure_selected_in_view_on_next_render: bool, } -impl State +impl TreeState where Identifier: Clone + PartialEq + Eq + core::hash::Hash, { @@ -38,9 +38,12 @@ where self.opened.iter().cloned().collect() } - /// Get a flat list of all visible (= below open) [`TreeItem`s](Item) with this `TreeState`. + /// Get a flat list of all visible (= below open) [`TreeItem`]s with this `TreeState`. #[must_use] - pub fn flatten<'a>(&self, items: &'a [Item<'a, Identifier>]) -> Vec> { + pub fn flatten<'a>( + &self, + items: &'a [TreeItem<'a, Identifier>], + ) -> Vec> { flatten(&self.opened, items) } @@ -86,7 +89,7 @@ where } /// Toggles a tree node. - /// If the node is in opened then it calls [`close`](State::close). Otherwise it calls [`open`](State::open). + /// If the node is in opened then it calls [`close`](Self::close). Otherwise it calls [`open`](Self::open). /// /// Returns `true` when a node is opened / closed. /// As toggle always changes something, this only returns `false` when an empty identifier is given. @@ -101,7 +104,7 @@ where } /// Toggles the currently selected tree node. - /// See also [`toggle`](State::toggle) + /// See also [`toggle`](Self::toggle) /// /// Returns `true` when a node is opened / closed. /// As toggle always changes something, this only returns `false` when nothing is selected. @@ -125,7 +128,7 @@ where /// Select the first node. /// /// Returns `true` when the selection changed. - pub fn select_first(&mut self, items: &[Item]) -> bool { + pub fn select_first(&mut self, items: &[TreeItem]) -> bool { let identifier = items .first() .map_or(Vec::new(), |item| vec![item.identifier.clone()]); @@ -135,7 +138,7 @@ where /// Select the last visible node. /// /// Returns `true` when the selection changed. - pub fn select_last(&mut self, items: &[Item]) -> bool { + pub fn select_last(&mut self, items: &[TreeItem]) -> bool { let visible = self.flatten(items); let new_identifier = visible .into_iter() @@ -149,7 +152,11 @@ where /// Returns `true` when the selection changed. /// /// This can be useful for mouse clicks. - pub fn select_visible_index(&mut self, items: &[Item], new_index: usize) -> bool { + pub fn select_visible_index( + &mut self, + items: &[TreeItem], + new_index: usize, + ) -> bool { let visible = self.flatten(items); let new_index = new_index.min(visible.len().saturating_sub(1)); let new_identifier = visible @@ -176,11 +183,11 @@ where /// }); /// ``` /// - /// For more examples take a look into the source code of [`key_up`](State::key_up) or [`key_down`](State::key_down). + /// For more examples take a look into the source code of [`key_up`](Self::key_up) or [`key_down`](Self::key_down). /// They are implemented with this method. pub fn select_visible_relative( &mut self, - items: &[Item], + items: &[TreeItem], change_function: F, ) -> bool where @@ -199,7 +206,7 @@ where self.select(new_identifier) } - /// Ensure the selected [`TreeItem`](Item) is visible on next render + /// Ensure the selected [`TreeItem`] is visible on next render pub fn scroll_selected_into_view(&mut self) { self.ensure_selected_in_view_on_next_render = true; } @@ -227,7 +234,7 @@ where /// Moves up in the current depth or to its parent. /// /// Returns `true` when the selection changed. - pub fn key_up(&mut self, items: &[Item]) -> bool { + pub fn key_up(&mut self, items: &[TreeItem]) -> bool { self.select_visible_relative(items, |current| { current.map_or(usize::MAX, |current| current.saturating_sub(1)) }) @@ -237,7 +244,7 @@ where /// Moves down in the current depth or into a child node. /// /// Returns `true` when the selection changed. - pub fn key_down(&mut self, items: &[Item]) -> bool { + pub fn key_down(&mut self, items: &[TreeItem]) -> bool { self.select_visible_relative(items, |current| { current.map_or(0, |current| current.saturating_add(1)) })