@@ -8,6 +8,7 @@ use ansi_term::Style;
8
8
use ignore:: DirEntry ;
9
9
use lscolors:: Style as LS_Style ;
10
10
use std:: {
11
+ borrow:: Cow ,
11
12
convert:: From ,
12
13
fmt:: { self , Display , Formatter } ,
13
14
ffi:: { OsStr , OsString } ,
@@ -77,6 +78,15 @@ impl Node {
77
78
& self . file_name
78
79
}
79
80
81
+ /// Converts `OsStr` to `String`; if fails does a lossy conversion replacing non-Unicode
82
+ /// sequences with Unicode replacement scalar value.
83
+ pub fn file_name_lossy ( & self ) -> Cow < ' _ , str > {
84
+ self . file_name ( ) . to_str ( ) . map_or_else (
85
+ || self . file_name ( ) . to_string_lossy ( ) ,
86
+ |s| Cow :: from ( s)
87
+ )
88
+ }
89
+
80
90
/// Returns `true` if node is a directory.
81
91
pub fn is_dir ( & self ) -> bool {
82
92
self . file_type ( )
@@ -146,17 +156,17 @@ impl Node {
146
156
let path = self . symlink_target_path ( ) . unwrap_or_else ( || self . path ( ) ) ;
147
157
148
158
if let Some ( icon) = path. extension ( ) . map ( icon_from_ext) . flatten ( ) {
149
- return self . stylize ( icon)
159
+ return Some ( self . stylize ( icon) ) ;
150
160
}
151
161
152
162
if let Some ( icon) = self . file_type ( ) . map ( icon_from_file_type) . flatten ( ) {
153
- return self . stylize ( icon) ;
163
+ return Some ( self . stylize ( icon) ) ;
154
164
}
155
165
156
166
let file_name = self . symlink_target_file_name ( ) . unwrap_or_else ( || self . file_name ( ) ) ;
157
167
158
168
if let Some ( icon) = icon_from_file_name ( file_name) {
159
- return self . stylize ( icon) ;
169
+ return Some ( self . stylize ( icon) ) ;
160
170
}
161
171
162
172
Some ( icons:: get_default_icon ( ) . to_owned ( ) )
@@ -165,20 +175,21 @@ impl Node {
165
175
/// Stylizes input, `entity` based on [`LS_COLORS`]
166
176
///
167
177
/// [`LS_COLORS`]: super::tree::ui::LS_COLORS
168
- fn stylize ( & self , entity : & str ) -> Option < String > {
169
- self . style ( )
170
- . foreground
171
- . map ( |fg| fg. bold ( ) . paint ( entity) . to_string ( ) )
172
- . or_else ( || Some ( entity . to_string ( ) ) )
178
+ fn stylize ( & self , entity : & str ) -> String {
179
+ self . style ( ) . foreground . map_or_else (
180
+ || entity . to_string ( ) ,
181
+ |fg| fg. bold ( ) . paint ( entity) . to_string ( )
182
+ )
173
183
}
174
184
175
185
/// Stylizes symlink name for display.
176
186
fn stylize_link_name ( & self ) -> Option < String > {
177
187
self . symlink_target_file_name ( )
178
188
. map ( |name| {
179
- let file_name = self . file_name ( ) . to_str ( ) . map ( |s| self . stylize ( s) ) . flatten ( ) . unwrap ( ) ;
180
- let target_name = Color :: Red . paint ( format ! ( "\u{2192} {}" , name. to_str( ) . unwrap( ) ) ) ;
181
- format ! ( "{} {}" , file_name, target_name)
189
+ let file_name = self . file_name_lossy ( ) ;
190
+ let styled_name = self . stylize ( & file_name) ;
191
+ let target_name = Color :: Red . paint ( format ! ( "\u{2192} {}" , name. to_string_lossy( ) ) ) ;
192
+ format ! ( "{} {}" , styled_name, target_name)
182
193
} )
183
194
}
184
195
}
@@ -268,11 +279,8 @@ impl Display for Node {
268
279
( name, padding)
269
280
} )
270
281
. or_else ( || {
271
- let name = self . file_name ( )
272
- . to_str ( )
273
- . map ( |name| self . stylize ( name) )
274
- . flatten ( )
275
- . unwrap ( ) ;
282
+ let file_name = self . file_name_lossy ( ) ;
283
+ let name = self . stylize ( & file_name) ;
276
284
let padding = name. len ( ) + 1 ;
277
285
278
286
Some ( ( name, padding) )
0 commit comments