1- use crate :: AnsiPrefixes ;
1+ use super :: { ChildPosition , TreeHorizontalSlice } ;
2+ use crate :: ls_colors:: LsColors ;
3+ use derive_more:: Display ;
24use std:: { collections:: HashMap , fmt, hash:: Hash } ;
5+ use zero_copy_pads:: Width ;
6+
7+ /// Coloring configuration: ANSI prefix strings from the environment and a name-to-color map.
8+ #[ derive( Debug ) ]
9+ pub struct Coloring < Name > {
10+ ansi_prefixes : LsColors ,
11+ map : HashMap < Name , Color > ,
12+ }
13+
14+ impl < Name : Hash + Eq > Coloring < Name > {
15+ /// Create a new [`Coloring`] from ANSI prefixes and a name-to-color map.
16+ pub fn new ( ansi_prefixes : LsColors , map : HashMap < Name , Color > ) -> Self {
17+ Coloring { ansi_prefixes, map }
18+ }
19+
20+ /// Return `(color, prefixes)` for a node, used to build a colored slice for rendering.
21+ pub ( crate ) fn node_color ( & self , name : & Name , has_children : bool ) -> Option < ( Color , & LsColors ) > {
22+ let color = if has_children {
23+ Some ( Color :: Directory )
24+ } else {
25+ self . map . get ( name) . copied ( )
26+ } ?;
27+ Some ( ( color, & self . ansi_prefixes ) )
28+ }
29+ }
330
431/// The coloring to apply to a node name.
532#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
@@ -16,24 +43,14 @@ pub enum Color {
1643
1744impl Color {
1845 /// Get the ANSI prefix for this color from the given prefix table.
19- pub fn ansi_prefix ( self , prefixes : & AnsiPrefixes ) -> AnsiPrefix < ' _ > {
20- AnsiPrefix ( match self {
21- Color :: Directory => & prefixes. directory ,
22- Color :: Normal => & prefixes. normal ,
23- Color :: Executable => & prefixes. executable ,
24- Color :: Symlink => & prefixes. symlink ,
25- } )
46+ pub fn ansi_prefix ( self , prefixes : & LsColors ) -> AnsiPrefix < ' _ > {
47+ AnsiPrefix ( prefixes. prefix_str ( self ) )
2648 }
2749}
2850
29- /// ANSI prefix wrapper for a [`Color`] variant, implements [`fmt::Display`].
30- pub struct AnsiPrefix < ' a > ( pub ( crate ) & ' a str ) ;
31-
32- impl fmt:: Display for AnsiPrefix < ' _ > {
33- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
34- f. write_str ( self . 0 )
35- }
36- }
51+ /// ANSI prefix wrapper for a [`Color`] variant, implements [`Display`].
52+ #[ derive( Display ) ]
53+ pub struct AnsiPrefix < ' a > ( & ' a str ) ;
3754
3855impl AnsiPrefix < ' _ > {
3956 /// Returns the reset suffix to emit after this prefix, or `""` if no prefix.
@@ -46,18 +63,35 @@ impl AnsiPrefix<'_> {
4663 }
4764}
4865
49- /// Coloring configuration: ANSI prefix strings from the environment and a name-to-color map.
50- #[ derive( Debug ) ]
51- pub struct Coloring < Name > {
52- /// ANSI prefix strings read from `LS_COLORS`.
53- pub ( crate ) ansi_prefixes : AnsiPrefixes ,
54- /// Map from node name to color.
55- pub ( crate ) map : HashMap < Name , Color > ,
66+ /// A [`TreeHorizontalSlice`] with its color applied, used for rendering.
67+ pub ( crate ) struct ColoredTreeHorizontalSlice < ' a > {
68+ pub ( crate ) slice : TreeHorizontalSlice < String > ,
69+ pub ( crate ) color : Color ,
70+ pub ( crate ) ansi_prefixes : & ' a LsColors ,
5671}
5772
58- impl < Name : Hash + Eq > Coloring < Name > {
59- /// Create a new [`Coloring`] from ANSI prefixes and a name-to-color map.
60- pub fn new ( ansi_prefixes : AnsiPrefixes , map : HashMap < Name , Color > ) -> Self {
61- Coloring { ansi_prefixes, map }
73+ impl fmt:: Display for ColoredTreeHorizontalSlice < ' _ > {
74+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
75+ let TreeHorizontalSlice {
76+ ancestor_relative_positions,
77+ skeletal_component,
78+ name,
79+ } = & self . slice ;
80+ for pos in ancestor_relative_positions {
81+ let connector = match pos {
82+ ChildPosition :: Init => "│ " ,
83+ ChildPosition :: Last => " " ,
84+ } ;
85+ write ! ( f, "{connector}" ) ?;
86+ }
87+ let prefix = self . color . ansi_prefix ( self . ansi_prefixes ) ;
88+ let suffix = prefix. suffix ( ) ;
89+ write ! ( f, "{skeletal_component}{prefix}{name}{suffix}" )
90+ }
91+ }
92+
93+ impl Width for ColoredTreeHorizontalSlice < ' _ > {
94+ fn width ( & self ) -> usize {
95+ self . slice . width ( )
6296 }
6397}
0 commit comments