ahc_evaluation/
config.rs

1use std::{
2    fs::read_to_string,
3    path::{Path, PathBuf},
4};
5
6use anyhow::Context;
7use itertools::Itertools;
8use serde::Deserialize;
9
10#[derive(Debug, Clone, Deserialize)]
11pub struct ThreadConfig {
12    /// Number of threads used for evaluation.
13    /// If not specified, it is determined automatically.
14    pub thread_num: Option<usize>,
15}
16
17#[derive(Debug, Clone, Deserialize)]
18pub struct PathConfig {
19    /// Path of the seed list file.
20    pub seed_file: std::path::PathBuf,
21
22    /// Path of the directory of input files.
23    pub input_dir: std::path::PathBuf,
24
25    /// Path of the directory of output files.
26    pub output_dir: std::path::PathBuf,
27
28    /// Path of the file that outputs the score and execution time for each seed.
29    pub evaluation_record: std::path::PathBuf,
30}
31
32#[derive(Debug, Clone, Deserialize)]
33pub struct Build {
34    /// Build command for submission code.
35    pub submission: Vec<String>,
36
37    /// Build command for local tester.
38    pub tester: Vec<String>,
39}
40
41#[derive(Debug, Clone, Deserialize)]
42pub struct Execute {
43    /// Command line arguments to execute the submission code.
44    pub submission: Vec<String>,
45
46    /// Command line arguments to execute the local tester.
47    ///
48    /// The following placeholders can be used (Placeholders must be quoted independently).
49    /// - `{input-path}`: The path of the input file corresponding to the seed.
50    /// - `{output-path}`: The path of the output file corresponding to the seed.
51    /// - `{submission-execute}`: Execution command of the submission code.
52    pub tester: Vec<String>,
53
54    /// Set this flag to `true` if the submission code is to be executed via the local tester rather than independently.
55    pub integrated: bool,
56}
57
58#[derive(Debug, Clone, Deserialize)]
59pub struct CommandConfig {
60    /// Command line arguments to build codes.
61    pub build: Build,
62
63    /// Command line arguments to execute codes.
64    pub execute: Execute,
65}
66
67#[derive(Debug, Clone, Deserialize)]
68pub struct Config {
69    /// Configuration of threads.
70    pub thread: ThreadConfig,
71
72    /// Configuration of paths.
73    pub path: PathConfig,
74
75    /// Configuration of command line arguments.
76    pub command: CommandConfig,
77}
78
79impl Config {
80    /// Reads the configuration from the file.
81    pub fn read_from_file<P>(config_file_path: P) -> anyhow::Result<Self>
82    where
83        P: AsRef<Path>,
84    {
85        let config_str = read_to_string(config_file_path)
86            .with_context(|| "Failed to read configuration file.")?;
87        toml::from_str(&config_str).with_context(|| "Failed to deserialize configuration file.")
88    }
89
90    /// Returns the path to the input file.
91    pub fn input_file_path(&self, seed: usize) -> PathBuf {
92        self.path.input_dir.join(format!("{:04}.txt", seed))
93    }
94
95    /// Returns the path to the output file.
96    pub fn output_file_path(&self, seed: usize) -> PathBuf {
97        self.path.output_dir.join(format!("{:04}.txt", seed))
98    }
99
100    /// Returns the command to execute the local tester with placeholders replaced.
101    pub fn cmd_args_for_execute_tester(&self, seed: usize) -> Vec<String> {
102        self.command
103            .execute
104            .tester
105            .iter()
106            .map(|arg| match arg.as_str() {
107                "{input}" => self.input_file_path(seed).to_str().unwrap().to_owned(),
108                "{output}" => self.output_file_path(seed).to_str().unwrap().to_owned(),
109                "{cmd}" => self.command.execute.submission.iter().join(" "),
110                _ => arg.clone(),
111            })
112            .collect()
113    }
114}