Repository: sharkdp/bat
File: src/bin/bat/config.rs (Rust)

Code before:
use std::ffi::OsString;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;

use shell_words;

use crate::directories::PROJECT_DIRS;

pub fn config_file() -> PathBuf {
    env::var("BAT_CONFIG_PATH")
        .ok()
        .map(PathBuf::from)
        .filter(|config_path| config_path.is_file())
        .unwrap_or_else(|| PROJECT_DIRS.config_dir().join("config"))
}

pub fn generate_config_file() {
    let config_file = config_file();
    if config_file.exists() {
        println!("A config file already exists at: {}", config_file.to_string_lossy());

        print!("Overwrite? (y/n): ");
        let _ = io::stdout().flush();
        let mut decision = String::new();
        io::stdin().read_line(&mut decision).expect("Failed to read input");

        if !decision.trim().eq_ignore_ascii_case("Y") {
            return;
        }
    } else {
        let config_dir = config_file.parent().unwrap();
        if !config_dir.exists() {
            fs::create_dir(config_dir).expect("Unable to create config directory");
        }
    }

    let default_config = "# Specify desired theme (e.g. \"TwoDark\")
#--theme=\"TwoDark\"

# Enable this to use italic text on the terminal (not supported on all terminals):
#--italic-text=always

# Uncomment the following line to disable automatic paging:
#--paging=never

# Use C++ syntax for .ino files
#--map-syntax \"*.ino:C++\"

# Use \".gitignore\"-style highlighting for \".ignore\" files
#--map-syntax \".ignore:Git Ignore\"

Review comment (suggestion):
If this function returns a `Result<…>`, you can simply use `.read_line(&mut decision)?` instead of `.expect(…)` which would kill the process in case of an error.

Code after:
use std::ffi::OsString;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;

use shell_words;

use crate::directories::PROJECT_DIRS;

pub fn config_file() -> PathBuf {
    env::var("BAT_CONFIG_PATH")
        .ok()
        .map(PathBuf::from)
        .filter(|config_path| config_path.is_file())
        .unwrap_or_else(|| PROJECT_DIRS.config_dir().join("config"))
}

pub fn generate_config_file() -> bat::errors::Result<()> {
    let config_file = config_file();
    if config_file.exists() {
        println!("A config file already exists at: {}", config_file.to_string_lossy());

        print!("Overwrite? (y/N): ");
        io::stdout().flush()?;
        let mut decision = String::new();
        io::stdin().read_line(&mut decision)?;

        if !decision.trim().eq_ignore_ascii_case("Y") {
            return Ok(());
        }
    } else {
        let config_dir = config_file.parent();
        match config_dir {
            Some(path) => fs::create_dir_all(path)?,
            None => return Ok(Err(format!("Unable to write config file to: {}", config_file.to_string_lossy()))?),
        }
    }

    let default_config = r#"# bat config

# Specify desired theme (e.g. "TwoDark").  Issue `bat --list-themes` for a list of all available themes
#--theme="TwoDark"

# Enable this to use italic text on the terminal (not supported on all terminals):
#--italic-text=always

# Uncomment the following line to disable automatic paging:
#--paging=never

# Use C++ syntax for .ino files
#--map-syntax "*.ino:C++"