Skip to content

Commit

Permalink
feat: TreeItem trait
Browse files Browse the repository at this point in the history
  • Loading branch information
EdJoPaTo committed May 6, 2024
1 parent a9da73a commit decb51f
Show file tree
Hide file tree
Showing 11 changed files with 626 additions and 407 deletions.
72 changes: 34 additions & 38 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,62 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion, Throughpu
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::widgets::StatefulWidget;
use tui_tree_widget::{Tree, TreeItem, TreeState};
use tui_tree_widget::json::JsonTreeItem;
use tui_tree_widget::{SimpleTreeItem, Tree, TreeState};

fn example_items() -> Vec<TreeItem<'static, &'static str>> {
fn example_items() -> Vec<SimpleTreeItem<'static>> {
vec![
TreeItem::new_leaf("a", "Alfa"),
TreeItem::new(
"b",
SimpleTreeItem::new_leaf("Alfa"),
SimpleTreeItem::new(
"Bravo",
vec![
TreeItem::new_leaf("c", "Charlie"),
TreeItem::new(
"d",
SimpleTreeItem::new_leaf("Charlie"),
SimpleTreeItem::new(
"Delta",
vec![
TreeItem::new_leaf("e", "Echo"),
TreeItem::new_leaf("f", "Foxtrot"),
SimpleTreeItem::new_leaf("Echo"),
SimpleTreeItem::new_leaf("Foxtrot"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("g", "Golf"),
SimpleTreeItem::new_leaf("Golf"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("h", "Hotel"),
TreeItem::new(
"i",
SimpleTreeItem::new_leaf("Hotel"),
SimpleTreeItem::new(
"India",
vec![
TreeItem::new_leaf("j", "Juliett"),
TreeItem::new_leaf("k", "Kilo"),
TreeItem::new_leaf("l", "Lima"),
TreeItem::new_leaf("m", "Mike"),
TreeItem::new_leaf("n", "November"),
SimpleTreeItem::new_leaf("Juliett"),
SimpleTreeItem::new_leaf("Kilo"),
SimpleTreeItem::new_leaf("Lima"),
SimpleTreeItem::new_leaf("Mike"),
SimpleTreeItem::new_leaf("November"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("o", "Oscar"),
TreeItem::new(
"p",
SimpleTreeItem::new_leaf("Oscar"),
SimpleTreeItem::new(
"Papa",
vec![
TreeItem::new_leaf("q", "Quebec"),
TreeItem::new_leaf("r", "Romeo"),
TreeItem::new_leaf("s", "Sierra"),
TreeItem::new_leaf("t", "Tango"),
TreeItem::new_leaf("u", "Uniform"),
TreeItem::new(
"v",
SimpleTreeItem::new_leaf("Quebec"),
SimpleTreeItem::new_leaf("Romeo"),
SimpleTreeItem::new_leaf("Sierra"),
SimpleTreeItem::new_leaf("Tango"),
SimpleTreeItem::new_leaf("Uniform"),
SimpleTreeItem::new(
"Victor",
vec![
TreeItem::new_leaf("w", "Whiskey"),
TreeItem::new_leaf("x", "Xray"),
TreeItem::new_leaf("y", "Yankee"),
SimpleTreeItem::new_leaf("Whiskey"),
SimpleTreeItem::new_leaf("Xray"),
SimpleTreeItem::new_leaf("Yankee"),
],
)
.expect("all item identifiers are unique"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("z", "Zulu"),
SimpleTreeItem::new_leaf("Zulu"),
]
}

Expand All @@ -88,7 +84,7 @@ fn init(criterion: &mut Criterion) {

group.bench_function("empty", |bencher| {
bencher.iter(|| {
black_box(Tree::<usize>::new(black_box(vec![])).unwrap());
black_box(Tree::<SimpleTreeItem>::new(black_box(vec![])).unwrap());
});
});

Expand All @@ -101,7 +97,7 @@ fn init(criterion: &mut Criterion) {
let metadata = metadata();
group.bench_function("metadata", |bencher| {
bencher.iter(|| {
black_box(Tree::new(tui_tree_widget::json::tree_items(black_box(&metadata))).unwrap());
black_box(Tree::new(JsonTreeItem::new(black_box(&metadata))).unwrap());
});
});

Expand All @@ -114,10 +110,10 @@ fn renders(criterion: &mut Criterion) {

let buffer_size = Rect::new(0, 0, 100, 50);

let tree = Tree::new(vec![]).unwrap();
let tree = Tree::<SimpleTreeItem>::new(vec![]).unwrap();
group.bench_function("empty", |bencher| {
bencher.iter_batched(
|| (tree.clone(), TreeState::<usize>::default()),
|| (tree.clone(), TreeState::default()),
|(tree, mut state)| {
let mut buffer = Buffer::empty(buffer_size);
black_box(tree).render(buffer_size, black_box(&mut buffer), &mut state);
Expand All @@ -139,7 +135,7 @@ fn renders(criterion: &mut Criterion) {
});

let metadata = metadata();
let tree = Tree::new(tui_tree_widget::json::tree_items(&metadata)).unwrap();
let tree = Tree::new(JsonTreeItem::new(&metadata)).unwrap();
group.bench_function("metadata", |bencher| {
bencher.iter_batched(
|| (tree.clone(), TreeState::default()),
Expand Down
3 changes: 2 additions & 1 deletion examples/cargo_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ratatui::text::Span;
use ratatui::widgets::{Block, Scrollbar, ScrollbarOrientation};
use ratatui::{Frame, Terminal};
use serde_json::Value;
use tui_tree_widget::json::JsonTreeItem;
use tui_tree_widget::{Selector, Tree, TreeState};

struct App {
Expand Down Expand Up @@ -37,7 +38,7 @@ impl App {

fn draw(&mut self, frame: &mut Frame) {
let area = frame.size();
let widget = Tree::new(tui_tree_widget::json::tree_items(&self.metadata))
let widget = Tree::new(JsonTreeItem::new(&self.metadata))
.expect("JSON Should always have unique identifiers")
.block(
Block::bordered()
Expand Down
169 changes: 106 additions & 63 deletions examples/example.rs → examples/custom_tree_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,79 +9,122 @@ use ratatui::widgets::{Block, Scrollbar, ScrollbarOrientation};
use ratatui::{Frame, Terminal};
use tui_tree_widget::{Tree, TreeItem, TreeState};

struct App<'a> {
state: TreeState<&'static str>,
items: Vec<TreeItem<'a, &'static str>>,
struct MyTreeItem<'a> {
identifier: String,
content: &'a str,
children: Vec<Self>,
}

impl<'a> App<'a> {
impl<'a> TreeItem for MyTreeItem<'a> {
type Identifier = String;

fn children(&self) -> &[Self] {
&self.children
}

fn height(&self) -> usize {
// We know that every item will have exactly the height 1
1
}

fn identifier(&self) -> &Self::Identifier {
&self.identifier
}

fn render(&self, area: ratatui::layout::Rect, buffer: &mut ratatui::buffer::Buffer) {
let line = ratatui::text::Line::raw(self.content);
ratatui::widgets::Widget::render(line, area, buffer);
}
}

impl<'a> MyTreeItem<'a> {
fn new_leaf(identifier: &str, content: &'a str) -> Self {
Self {
identifier: identifier.to_owned(),
content,
children: Vec::new(),
}
}

fn new(identifier: &str, content: &'a str, children: Vec<Self>) -> Self {
tui_tree_widget::unique_identifiers::children(&children)
.expect("all item identifiers are unique");
Self {
identifier: identifier.to_owned(),
content,
children,
}
}

fn example() -> Vec<Self> {
vec![
Self::new_leaf("a", "Alfa"),
Self::new(
"b",
"Bravo",
vec![
Self::new_leaf("c", "Charlie"),
Self::new(
"d",
"Delta",
vec![Self::new_leaf("e", "Echo"), Self::new_leaf("f", "Foxtrot")],
),
Self::new_leaf("g", "Golf"),
],
),
Self::new_leaf("h", "Hotel"),
Self::new(
"i",
"India",
vec![
Self::new_leaf("j", "Juliett"),
Self::new_leaf("k", "Kilo"),
Self::new_leaf("l", "Lima"),
Self::new_leaf("m", "Mike"),
Self::new_leaf("n", "November"),
],
),
Self::new_leaf("o", "Oscar"),
Self::new(
"p",
"Papa",
vec![
Self::new_leaf("q", "Quebec"),
Self::new_leaf("r", "Romeo"),
Self::new_leaf("s", "Sierra"),
Self::new_leaf("t", "Tango"),
Self::new_leaf("u", "Uniform"),
Self::new(
"v",
"Victor",
vec![
Self::new_leaf("w", "Whiskey"),
Self::new_leaf("x", "Xray"),
Self::new_leaf("y", "Yankee"),
],
),
],
),
Self::new_leaf("z", "Zulu"),
]
}
}

struct App {
state: TreeState<String>,
}

impl App {
fn new() -> Self {
Self {
state: TreeState::default(),
items: vec![
TreeItem::new_leaf("a", "Alfa"),
TreeItem::new(
"b",
"Bravo",
vec![
TreeItem::new_leaf("c", "Charlie"),
TreeItem::new(
"d",
"Delta",
vec![
TreeItem::new_leaf("e", "Echo"),
TreeItem::new_leaf("f", "Foxtrot"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("g", "Golf"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("h", "Hotel"),
TreeItem::new(
"i",
"India",
vec![
TreeItem::new_leaf("j", "Juliett"),
TreeItem::new_leaf("k", "Kilo"),
TreeItem::new_leaf("l", "Lima"),
TreeItem::new_leaf("m", "Mike"),
TreeItem::new_leaf("n", "November"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("o", "Oscar"),
TreeItem::new(
"p",
"Papa",
vec![
TreeItem::new_leaf("q", "Quebec"),
TreeItem::new_leaf("r", "Romeo"),
TreeItem::new_leaf("s", "Sierra"),
TreeItem::new_leaf("t", "Tango"),
TreeItem::new_leaf("u", "Uniform"),
TreeItem::new(
"v",
"Victor",
vec![
TreeItem::new_leaf("w", "Whiskey"),
TreeItem::new_leaf("x", "Xray"),
TreeItem::new_leaf("y", "Yankee"),
],
)
.expect("all item identifiers are unique"),
],
)
.expect("all item identifiers are unique"),
TreeItem::new_leaf("z", "Zulu"),
],
}
}

fn draw(&mut self, frame: &mut Frame) {
let area = frame.size();
let widget = Tree::new(self.items.clone())
let items = MyTreeItem::example();
let widget = Tree::new(items)
.expect("all item identifiers are unique")
.block(
Block::bordered()
Expand Down
Loading

0 comments on commit decb51f

Please sign in to comment.