"Fossies" - the Fresh Open Source Software Archive

Member "fd-8.1.1/src/output.rs" (25 May 2020, 3664 Bytes) of package /linux/privat/fd-8.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Rust source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "output.rs": 8.0.0_vs_8.1.0.

    1 use std::io::{self, StdoutLock, Write};
    2 use std::path::{Path, PathBuf};
    3 use std::process;
    4 use std::sync::atomic::{AtomicBool, Ordering};
    5 use std::sync::Arc;
    6 
    7 use ansi_term;
    8 use lscolors::{LsColors, Style};
    9 
   10 use crate::exit_codes::ExitCode;
   11 use crate::filesystem::strip_current_dir;
   12 use crate::options::Options;
   13 
   14 pub fn replace_path_separator(path: &str, new_path_separator: &str) -> String {
   15     path.replace(std::path::MAIN_SEPARATOR, &new_path_separator)
   16 }
   17 
   18 // TODO: this function is performance critical and can probably be optimized
   19 pub fn print_entry(
   20     stdout: &mut StdoutLock,
   21     entry: &PathBuf,
   22     config: &Options,
   23     wants_to_quit: &Arc<AtomicBool>,
   24 ) {
   25     let path = if entry.is_absolute() {
   26         entry.as_path()
   27     } else {
   28         strip_current_dir(entry)
   29     };
   30 
   31     let r = if let Some(ref ls_colors) = config.ls_colors {
   32         print_entry_colorized(stdout, path, config, ls_colors, &wants_to_quit)
   33     } else {
   34         print_entry_uncolorized(stdout, path, config)
   35     };
   36 
   37     if r.is_err() {
   38         // Probably a broken pipe. Exit gracefully.
   39         process::exit(ExitCode::GeneralError.into());
   40     }
   41 }
   42 
   43 // TODO: this function is performance critical and can probably be optimized
   44 fn print_entry_colorized(
   45     stdout: &mut StdoutLock,
   46     path: &Path,
   47     config: &Options,
   48     ls_colors: &LsColors,
   49     wants_to_quit: &Arc<AtomicBool>,
   50 ) -> io::Result<()> {
   51     let default_style = ansi_term::Style::default();
   52 
   53     // Traverse the path and colorize each component
   54     for (component, style) in ls_colors.style_for_path_components(path) {
   55         let style = style
   56             .map(Style::to_ansi_term_style)
   57             .unwrap_or(default_style);
   58 
   59         let mut path_string = component.to_string_lossy();
   60         if let Some(ref separator) = config.path_separator {
   61             *path_string.to_mut() = replace_path_separator(&path_string, &separator);
   62         }
   63         write!(stdout, "{}", style.paint(path_string))?;
   64 
   65         // TODO: can we move this out of the if-statement? Why do we call it that often?
   66         if wants_to_quit.load(Ordering::Relaxed) {
   67             writeln!(stdout)?;
   68             process::exit(ExitCode::KilledBySigint.into());
   69         }
   70     }
   71 
   72     if config.null_separator {
   73         write!(stdout, "\0")
   74     } else {
   75         writeln!(stdout)
   76     }
   77 }
   78 
   79 // TODO: this function is performance critical and can probably be optimized
   80 fn print_entry_uncolorized_base(
   81     stdout: &mut StdoutLock,
   82     path: &Path,
   83     config: &Options,
   84 ) -> io::Result<()> {
   85     let separator = if config.null_separator { "\0" } else { "\n" };
   86 
   87     let mut path_string = path.to_string_lossy();
   88     if let Some(ref separator) = config.path_separator {
   89         *path_string.to_mut() = replace_path_separator(&path_string, &separator);
   90     }
   91     write!(stdout, "{}{}", path_string, separator)
   92 }
   93 
   94 #[cfg(not(unix))]
   95 fn print_entry_uncolorized(
   96     stdout: &mut StdoutLock,
   97     path: &Path,
   98     config: &Options,
   99 ) -> io::Result<()> {
  100     print_entry_uncolorized_base(stdout, path, config)
  101 }
  102 
  103 #[cfg(unix)]
  104 fn print_entry_uncolorized(
  105     stdout: &mut StdoutLock,
  106     path: &Path,
  107     config: &Options,
  108 ) -> io::Result<()> {
  109     use std::os::unix::ffi::OsStrExt;
  110 
  111     if config.interactive_terminal || config.path_separator.is_some() {
  112         // Fall back to the base implementation
  113         print_entry_uncolorized_base(stdout, path, config)
  114     } else {
  115         // Print path as raw bytes, allowing invalid UTF-8 filenames to be passed to other processes
  116         let separator = if config.null_separator { b"\0" } else { b"\n" };
  117         stdout.write_all(path.as_os_str().as_bytes())?;
  118         stdout.write_all(separator)
  119     }
  120 }