solverforge_config/
solver_config.rs1use std::path::Path;
2use std::time::Duration;
3
4use serde::{Deserialize, Serialize};
5
6use crate::director::DirectorConfig;
7use crate::error::ConfigError;
8use crate::phase::PhaseConfig;
9use crate::termination::TerminationConfig;
10
11#[derive(Debug, Clone, Default, Deserialize, Serialize)]
13#[serde(rename_all = "snake_case")]
14pub struct SolverConfig {
15 #[serde(default)]
17 pub environment_mode: EnvironmentMode,
18
19 #[serde(default)]
21 pub random_seed: Option<u64>,
22
23 #[serde(default)]
25 pub move_thread_count: MoveThreadCount,
26
27 #[serde(default)]
29 pub termination: Option<TerminationConfig>,
30
31 #[serde(default)]
33 pub score_director: Option<DirectorConfig>,
34
35 #[serde(default)]
37 pub phases: Vec<PhaseConfig>,
38}
39
40impl SolverConfig {
41 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn load(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
52 Self::from_toml_file(path)
53 }
54
55 pub fn from_toml_file(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
57 let contents = std::fs::read_to_string(path)?;
58 Self::from_toml_str(&contents)
59 }
60
61 pub fn from_toml_str(s: &str) -> Result<Self, ConfigError> {
63 Ok(toml::from_str(s)?)
64 }
65
66 pub fn from_yaml_file(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
68 let contents = std::fs::read_to_string(path)?;
69 Self::from_yaml_str(&contents)
70 }
71
72 pub fn from_yaml_str(s: &str) -> Result<Self, ConfigError> {
74 Ok(serde_yaml::from_str(s)?)
75 }
76
77 pub fn with_termination_seconds(mut self, seconds: u64) -> Self {
79 self.termination = Some(TerminationConfig {
80 seconds_spent_limit: Some(seconds),
81 ..self.termination.unwrap_or_default()
82 });
83 self
84 }
85
86 pub fn with_random_seed(mut self, seed: u64) -> Self {
88 self.random_seed = Some(seed);
89 self
90 }
91
92 pub fn with_phase(mut self, phase: PhaseConfig) -> Self {
94 self.phases.push(phase);
95 self
96 }
97
98 pub fn time_limit(&self) -> Option<Duration> {
116 self.termination.as_ref().and_then(|t| t.time_limit())
117 }
118}
119
120#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize)]
122#[serde(rename_all = "snake_case")]
123pub enum EnvironmentMode {
124 #[default]
126 NonReproducible,
127
128 Reproducible,
130
131 FastAssert,
133
134 FullAssert,
136}
137
138#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
140#[serde(rename_all = "snake_case")]
141pub enum MoveThreadCount {
142 #[default]
144 Auto,
145
146 None,
148
149 Count(usize),
151}
152
153#[derive(Debug, Clone, Default)]
155pub struct SolverConfigOverride {
156 pub termination: Option<TerminationConfig>,
158}
159
160impl SolverConfigOverride {
161 pub fn with_termination(termination: TerminationConfig) -> Self {
163 SolverConfigOverride {
164 termination: Some(termination),
165 }
166 }
167}