<commit_before>#[macro_use]
extern crate serde_derive;

extern crate serde;

extern crate toml;
extern crate clap;

use clap::{App, Arg, ArgMatches};
use std::path::Path;
use std::fs::{create_dir, File};
use std::io::prelude::*;

#[derive(Serialize, Deserialize)]
struct Config {
    data_dir: Option<String>,
}

const CONFIG_PATH: &'static str = "/etc/blochs/";
const CONFIG_FILE_NAME: &'static str = "server.toml";
const DEFAULT_DATA_DIR: &'static str = "/var/lib/blochs/";

fn main() {
    let options = get_provided_options();

    let config_path = Path::new(CONFIG_PATH);
    if !config_path.exists() {
        match create_dir(CONFIG_PATH) {
            Err(err) => panic!("Could not create the config directory under {}: {}", CONFIG_PATH, err),
            Ok(_) => {}
        };
    }

    let config_file_path = config_path.join(CONFIG_FILE_NAME);
    let mut read_config_file = match File::open(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut actual_content = String::new();
    match read_config_file.read_to_string(&mut actual_content) {
        Ok(_) => {},
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut config_values: Config = toml::from_str(&actual_content).unwrap();

    let config_or_default_data_dir = config_values.data_dir.unwrap_or(DEFAULT_DATA_DIR.to_string());

    let new_data_dir = options.value_of("data.dir").unwrap_or(&config_or_default_data_dir);

    config_values.data_dir = Some(new_data_dir.to_string());

    let new_config_content = toml::to_string(&config_values).unwrap();


    let mut write_config_file = match File::create(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    match write_config_file.write_all(new_config_content.as_bytes()) {
        Ok(_) => println!("New config saved at {}:\n\n{}", config_file_path.display(), new_config_content),
        Err(why) => panic!("Could not write config file {:?}: {}", config_file_path.display(), why),
    };
}

fn get_provided_options<'a>() -> ArgMatches<'a> {
    return App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .arg(Arg::with_name("data.dir")
            .long("data-dir")
            .value_name("DIR")
            .help(&format!("Sets where database data will be stored (default {})", DEFAULT_DATA_DIR))
        ).get_matches();
}<commit_msg>extract path creation to a function<commit_after>#[macro_use]
extern crate serde_derive;

extern crate serde;

extern crate toml;
extern crate clap;

use clap::{App, Arg, ArgMatches};
use std::path::Path;
use std::fs::{create_dir, File};
use std::io::prelude::*;

#[derive(Serialize, Deserialize)]
struct Config {
    data_dir: Option<String>,
}

const CONFIG_PATH: &'static str = "/etc/blochs/";
const CONFIG_FILE_NAME: &'static str = "server.toml";
const DEFAULT_DATA_DIR: &'static str = "/var/lib/blochs/";

fn main() {
    let options = get_provided_options();

    let config_path = Path::new(CONFIG_PATH);
    ensure_dir_exists(&config_path);

    let config_file_path = config_path.join(CONFIG_FILE_NAME);
    let mut read_config_file = match File::open(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut actual_content = String::new();
    match read_config_file.read_to_string(&mut actual_content) {
        Ok(_) => {},
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    let mut config_values: Config = toml::from_str(&actual_content).unwrap();

    let config_or_default_data_dir = config_values.data_dir.unwrap_or(DEFAULT_DATA_DIR.to_string());

    let new_data_dir = options.value_of("data.dir").unwrap_or(&config_or_default_data_dir);

    config_values.data_dir = Some(new_data_dir.to_string());

    let new_config_content = toml::to_string(&config_values).unwrap();


    let mut write_config_file = match File::create(config_file_path.as_path()) {
        Ok(file) => file,
        Err(err) => panic!("Could not open config file {:?}: {}", config_file_path.display(), err),
    };

    match write_config_file.write_all(new_config_content.as_bytes()) {
        Ok(_) => println!("New config saved at {}:\n\n{}", config_file_path.display(), new_config_content),
        Err(why) => panic!("Could not write config file {:?}: {}", config_file_path.display(), why),
    };
}

fn ensure_dir_exists(path: &Path) {
    if !path.exists() {
        match create_dir(path) {
            Err(err) => panic!("Could not create directory under {}: {}", path.display(), err),
            Ok(_) => {}
        };
    }
}

fn get_provided_options<'a>() -> ArgMatches<'a> {
    return App::new(env!("CARGO_PKG_NAME"))
        .version(env!("CARGO_PKG_VERSION"))
        .author(env!("CARGO_PKG_AUTHORS"))
        .about(env!("CARGO_PKG_DESCRIPTION"))
        .arg(Arg::with_name("data.dir")
            .long("data-dir")
            .value_name("DIR")
            .help(&format!("Sets where database data will be stored (default {})", DEFAULT_DATA_DIR))
        ).get_matches();
}
{'fraction_non_alphanumeric': 0.1625733137829912, 'fraction_numerical': 0.0, 'mean_word_length': 3.8723214285714285, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1327298', 'n_tokens_mistral': 1809, 'n_tokens_neox': 1819, 'n_words': 351}