1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use dirs;
use std::env;
use std::fs;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

pub fn compose<P: AsRef<Path>>(path: P, extension: Option<&str>) -> io::Result<File> {
    let mut file = match fs::metadata(&path) {
        Ok(metadata) => {
            if metadata.len() == 0 {
                File::create(&path)?
            } else {
                panic!("File already exists")
            }
        }
        Err(error) => match error.kind() {
            io::ErrorKind::NotFound => File::create(&path)?,
            _ => panic!(
                "Cannot read the metadata of existing file {}\nError: {}",
                path.as_ref().display(),
                &error
            ),
        },
    };

    if let Some(extension) = extension {
        fill_file(&mut file, extension);
    }
    Ok(file)
}

fn fill_file(file: &mut File, extension: &str) {
    let contents = template_contents(extension).unwrap_or_else(|| {
        println!(
            "No template file found for extension {}, creating an empty file",
            &extension
        );
        String::default()
    });

    file.write(contents.as_bytes())
        .expect("Unable to write file");
}

fn template_contents(extension: &str) -> Option<String> {
    let extension_path: PathBuf = ["templates", extension].iter().collect();
    let base_paths = [
        dirs::config_dir().unwrap().join("compose"),
        dirs::data_local_dir().unwrap().join("compose"),
        PathBuf::from(env!("CARGO_MANIFEST_DIR")),
    ];
    let template_paths = base_paths.iter().map(|path| path.join(&extension_path));

    for path in template_paths {
        if path.exists() {
            let contents = fs::read_to_string(&path);
            match contents {
                Ok(contents) => return Some(contents),
                Err(error) => println!(
                    "Template file '{}' could not be read!\nError: {}",
                    path.display(),
                    &error
                ),
            }
        } else {
            println!(
                "Template file '{}' does not exist, skipping...",
                path.display()
            );
        }
    }
    None
}