Skip to content

Commit

Permalink
Unify sorting to start dealing with selections
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Thiel committed Jun 3, 2019
1 parent b3dc836 commit 0b3e158
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 38 deletions.
21 changes: 18 additions & 3 deletions src/common.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
use crate::interactive::{Tree, TreeIndex};
use crate::interactive::{widgets::SortMode, EntryData, Tree, TreeIndex};
use itertools::Itertools;
use jwalk::WalkDir;
use std::fmt;
use std::path::Path;
use petgraph::Direction;
use std::{fmt, path::Path};

pub(crate) fn get_size_or_panic(tree: &Tree, node_idx: TreeIndex) -> u64 {
tree.node_weight(node_idx)
.expect("node should always be retrievable with valid index")
.size
}

pub(crate) fn sorted_entries(
tree: &Tree,
node_idx: TreeIndex,
sorting: SortMode,
) -> std::vec::IntoIter<(TreeIndex, &EntryData)> {
use SortMode::*;
tree.neighbors_directed(node_idx, Direction::Outgoing)
.filter_map(|idx| tree.node_weight(idx).map(|w| (idx, w)))
.sorted_by(|(_, l), (_, r)| match sorting {
SizeDescending => r.size.cmp(&l.size),
SizeAscending => l.size.cmp(&r.size),
})
}

/// Specifies a way to format bytes
#[derive(Clone, Copy)]
pub enum ByteFormat {
Expand Down
14 changes: 10 additions & 4 deletions src/interactive/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::widgets::{DisplayState, MainWindow};
use crate::{interactive::Traversal, ByteFormat, WalkOptions, WalkResult};
use crate::{interactive::Traversal, sorted_entries, ByteFormat, WalkOptions, WalkResult};
use failure::Error;
use std::{io, path::PathBuf};
use termion::input::{Keys, TermReadEventsAndRaw};
Expand Down Expand Up @@ -99,11 +99,17 @@ impl TerminalApp {
})?;
Ok(())
})?;

let sorting = Default::default();
let root = traversal.root_index;
let selected = sorted_entries(&traversal.tree, root, sorting)
.next()
.map(|(idx, _)| idx);
Ok(TerminalApp {
state: DisplayState {
root: traversal.root_index,
selected: None,
sorting: Default::default(),
root,
selected,
sorting,
},
display: display_options,
traversal: traversal,
Expand Down
34 changes: 11 additions & 23 deletions src/interactive/widgets.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::{DisplayOptions, Traversal, Tree, TreeIndex};
use crate::ByteFormat;
use itertools::Itertools;
use crate::{sorted_entries, ByteFormat};
use tui::layout::{Constraint, Direction, Layout};
use tui::style::{Color, Style};
use tui::{
Expand Down Expand Up @@ -126,27 +125,16 @@ impl<'a> Widget for Entries<'a> {
display,
sorting,
} = self;
use petgraph::Direction;
use SortMode::*;
List::new(
tree.neighbors_directed(*root, Direction::Outgoing)
.filter_map(|w| tree.node_weight(w))
.sorted_by(|l, r| match sorting {
SizeDescending => l.size.cmp(&r.size),
SizeAscending => r.size.cmp(&l.size),
})
.rev()
.map(|w| {
Text::Raw(
format!(
"{} | ----- | {}",
display.byte_format.display(w.size),
w.name.to_string_lossy()
)
.into(),
)
}),
)
List::new(sorted_entries(tree, *root, *sorting).map(|(_, w)| {
Text::Raw(
format!(
"{} | ----- | {}",
display.byte_format.display(w.size),
w.name.to_string_lossy()
)
.into(),
)
}))
.block(Block::default().borders(Borders::ALL).title("Entries"))
.start_corner(Corner::TopLeft)
.draw(area, buf);
Expand Down
27 changes: 19 additions & 8 deletions tests/interactive.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod app {
use dua::interactive::TreeIndex;
use dua::{
interactive::{widgets::SortMode, EntryData, TerminalApp, Tree, TreeIndexType},
ByteFormat, Color, TraversalSorting, WalkOptions,
Expand Down Expand Up @@ -44,32 +43,44 @@ mod app {
Ok(())
}

fn node_by(app: &TerminalApp, id: TreeIndexType) -> &EntryData {
app.traversal.tree.node_weight(id.into()).unwrap()
}

#[test]
fn simple_user_journey() -> Result<(), Error> {
let long_root = "sample-02/dir";
let (mut terminal, mut app) = initialized_app_and_terminal(&["sample-02", long_root])?;

// after initialization, we expect that...
assert_eq!(
app.state.sorting,
SortMode::SizeDescending,
"it starts in descending order by size"
"it will sort entries in descending order by size"
);

assert_eq!(
app.traversal
.tree
.node_weight(TreeIndex::new(11))
.unwrap()
.name,
node_by(&app, 11).name,
OsString::from(format!("{}/{}", FIXTURE_PATH, long_root)),
"the roots are always listed with the given (possibly long) names",
);

assert_eq!(
node_by(&app, 1).name,
node_by(
&app,
app.state.selected.as_ref().unwrap().index() as TreeIndexType
)
.name,
"it selects the first node in the list",
);

// when hitting the S key
app.process_events(&mut terminal, b"s".keys())?;
assert_eq!(
app.state.sorting,
SortMode::SizeAscending,
"it sets the sort to size ascending"
"it sets the sort mode to ascending by size"
);

Ok(())
Expand Down

0 comments on commit 0b3e158

Please sign in to comment.