docker_puzzles/
dockerfile_builder.rs

1use crate::error::UserError;
2use regex::Regex;
3use std::collections::HashMap;
4use std::error::Error;
5use std::fs::File;
6use std::io::{BufRead, BufReader, Write};
7use std::path::Path;
8
9pub fn build<S: ::std::hash::BuildHasher>(
10    puzzlefile_path: &Path,
11    puzzles: &HashMap<String, String, S>,
12) -> Result<(), Box<dyn Error>> {
13    let puzzlefile = File::open(puzzlefile_path)?;
14    let mut dockerfile = File::create(get_dockerfile_path(puzzlefile_path)?)?;
15
16    for line in BufReader::new(puzzlefile).lines() {
17        let input = line.unwrap();
18        let output = parse_line(input, puzzles)? + "\n";
19        dockerfile.write_all(output.as_bytes())?;
20    }
21
22    Ok(())
23}
24
25fn get_dockerfile_path(puzzlefile_path: &Path) -> Result<String, Box<dyn Error>> {
26    if let Some(parent_path) = puzzlefile_path.parent() {
27        if let Some(parent_path) = parent_path.to_str() {
28            return Ok(parent_path.to_owned() + "/Dockerfile");
29        }
30    }
31    Err(UserError::boxed("Cannot find parent directory"))
32}
33
34fn parse_line<S: ::std::hash::BuildHasher>(
35    input: String,
36    puzzles: &HashMap<String, String, S>,
37) -> Result<String, Box<dyn Error>> {
38    let regex = Regex::new(r"^PUZZLE (.+)").unwrap();
39    if regex.is_match(&input) {
40        let captures = regex.captures(&input).unwrap();
41        return match puzzles.get(&captures[1]) {
42            Some(puzzle) => Ok(puzzle.to_string()),
43            None => Err(UserError::boxed("Undefined puzzle")),
44        };
45    }
46    Ok(input)
47}