Skip to content

Commit e7dee6b

Browse files
KSXGitHubclaude
andauthored
refactor: move coloring logic from methods.rs into coloring.rs (#343)
Co-authored-by: Claude <noreply@anthropic.com>
1 parent aea511c commit e7dee6b

2 files changed

Lines changed: 45 additions & 53 deletions

File tree

src/visualizer/coloring.rs

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,6 @@ impl<'a> Coloring<'a> {
1616
pub fn new(ls_colors: LsColors, map: HashMap<Vec<&'a OsStr>, Color>) -> Self {
1717
Coloring { ls_colors, map }
1818
}
19-
20-
/// Return `(color, ls_colors)` for a node, used to build a colored slice for rendering.
21-
pub(super) fn node_color(
22-
&self,
23-
path_components: &[&'a OsStr],
24-
has_children: bool,
25-
) -> Option<(Color, &LsColors)> {
26-
let color = if has_children {
27-
Some(Color::Directory)
28-
} else {
29-
self.map.get(path_components).copied()
30-
}?;
31-
Some((color, &self.ls_colors))
32-
}
3319
}
3420

3521
/// The coloring to apply to a node name.
@@ -46,19 +32,15 @@ pub enum Color {
4632
}
4733

4834
impl Color {
49-
// TODO: reconsider the visibility of this function once the TODOs in
50-
// `visualizer/methods.rs` have been dealt with.
5135
/// Get the ANSI prefix for this color from the given prefix table.
52-
pub(super) fn ansi_prefix(self, prefixes: &LsColors) -> AnsiPrefix<'_> {
36+
fn ansi_prefix(self, prefixes: &LsColors) -> AnsiPrefix<'_> {
5337
AnsiPrefix(prefixes.prefix_str(self))
5438
}
5539
}
5640

57-
// TODO: reconsider the of this struct once the TODOs in
58-
// `visualizer/methods.rs` have been dealt with.
5941
/// ANSI prefix wrapper for a [`Color`] variant, implements [`Display`].
6042
#[derive(Display)]
61-
pub(super) struct AnsiPrefix<'a>(&'a str);
43+
struct AnsiPrefix<'a>(&'a str);
6244

6345
impl AnsiPrefix<'_> {
6446
/// Returns the reset suffix to emit after this prefix, or `""` if no prefix.
@@ -73,11 +55,9 @@ impl AnsiPrefix<'_> {
7355

7456
/// A [`TreeHorizontalSlice`] with its color applied, used for rendering.
7557
pub(super) struct ColoredTreeHorizontalSlice<'a> {
76-
// TODO: reconsider the following visibilities once the TODOs in
77-
// `visualizer/methods.rs` have been dealt with.
78-
pub(super) slice: TreeHorizontalSlice<String>,
79-
pub(super) color: Color,
80-
pub(super) ls_colors: &'a LsColors,
58+
slice: TreeHorizontalSlice<String>,
59+
color: Color,
60+
ls_colors: &'a LsColors,
8161
}
8262

8363
impl fmt::Display for ColoredTreeHorizontalSlice<'_> {
@@ -106,6 +86,37 @@ impl Width for ColoredTreeHorizontalSlice<'_> {
10686
}
10787
}
10888

89+
/// Wrap a [`TreeHorizontalSlice`] with color if coloring is available, otherwise return it as-is.
90+
///
91+
/// Path components are only constructed when coloring is enabled, avoiding
92+
/// unnecessary allocation in the common no-color case.
93+
pub(super) fn maybe_colored_slice<'a, 'b>(
94+
coloring: Option<&'b Coloring<'a>>,
95+
ancestors: impl Iterator<Item = &'a OsStr>,
96+
name: &'a OsStr,
97+
has_children: bool,
98+
slice: TreeHorizontalSlice<String>,
99+
) -> MaybeColoredTreeHorizontalSlice<'b> {
100+
let coloring = match coloring {
101+
Some(coloring) => coloring,
102+
None => return MaybeColoredTreeHorizontalSlice::Colorless(slice),
103+
};
104+
let path_components: Vec<&OsStr> = ancestors.chain(std::iter::once(name)).collect();
105+
let color = if has_children {
106+
Some(Color::Directory)
107+
} else {
108+
coloring.map.get(&path_components).copied()
109+
};
110+
match color {
111+
Some(color) => MaybeColoredTreeHorizontalSlice::Colorful(ColoredTreeHorizontalSlice {
112+
slice,
113+
color,
114+
ls_colors: &coloring.ls_colors,
115+
}),
116+
None => MaybeColoredTreeHorizontalSlice::Colorless(slice),
117+
}
118+
}
119+
109120
/// Either a [`TreeHorizontalSlice`] (colorless) or a [`ColoredTreeHorizontalSlice`] (colorful).
110121
#[derive(Display)]
111122
pub(super) enum MaybeColoredTreeHorizontalSlice<'a> {

src/visualizer/methods.rs

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,9 @@ use node_info::*;
1212
use table::*;
1313
use tree_table::*;
1414

15-
use super::{
16-
coloring::{ColoredTreeHorizontalSlice, MaybeColoredTreeHorizontalSlice},
17-
ColumnWidthDistribution, Visualizer,
18-
};
15+
use super::{coloring::maybe_colored_slice, ColumnWidthDistribution, Visualizer};
1916
use crate::size;
20-
use pipe_trait::Pipe;
21-
use std::{cmp::min, ffi::OsStr, fmt::Display, iter::once};
17+
use std::{cmp::min, ffi::OsStr, fmt::Display};
2218
use zero_copy_pads::{align_left, align_right};
2319

2420
impl<'a, Name, Size> Visualizer<'a, Name, Size>
@@ -95,28 +91,13 @@ where
9591
tree_horizontal_slice,
9692
} = tree_row;
9793

98-
// TODO: move this `colored` code block into `visualizer/coloring.rs`.
99-
let colored = self.coloring.and_then(|coloring| {
100-
let path_components: Vec<&OsStr> = initial_row
101-
.ancestors
102-
.iter()
103-
.map(|node| node.name.as_ref())
104-
.chain(initial_row.node_info.name.pipe_as_ref(once))
105-
.collect();
106-
coloring.node_color(&path_components, initial_row.node_info.children_count > 0)
107-
});
108-
109-
// TODO: move this `tree` code block into `visualizer/coloring.rs`.
110-
let tree = match colored {
111-
Some((color, ls_colors)) => {
112-
MaybeColoredTreeHorizontalSlice::Colorful(ColoredTreeHorizontalSlice {
113-
slice: tree_horizontal_slice,
114-
color,
115-
ls_colors,
116-
})
117-
}
118-
None => MaybeColoredTreeHorizontalSlice::Colorless(tree_horizontal_slice),
119-
};
94+
let tree = maybe_colored_slice(
95+
self.coloring,
96+
initial_row.ancestors.iter().map(|node| node.name.as_ref()),
97+
initial_row.node_info.name.as_ref(),
98+
initial_row.node_info.children_count > 0,
99+
tree_horizontal_slice,
100+
);
120101

121102
format!(
122103
"{size} {tree}│{bar}│{ratio}",

0 commit comments

Comments
 (0)