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 {
42 Self::default()
43 }
44
45 pub fn load(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
51 Self::from_toml_file(path)
52 }
53
54 pub fn from_toml_file(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
56 let contents = std::fs::read_to_string(path)?;
57 Self::from_toml_str(&contents)
58 }
59
60 pub fn from_toml_str(s: &str) -> Result<Self, ConfigError> {
62 Ok(toml::from_str(s)?)
63 }
64
65 pub fn from_yaml_file(path: impl AsRef<Path>) -> Result<Self, ConfigError> {
67 let contents = std::fs::read_to_string(path)?;
68 Self::from_yaml_str(&contents)
69 }
70
71 pub fn from_yaml_str(s: &str) -> Result<Self, ConfigError> {
73 Ok(serde_yaml::from_str(s)?)
74 }
75
76 pub fn with_termination_seconds(mut self, seconds: u64) -> Self {
77 self.termination = Some(TerminationConfig {
78 seconds_spent_limit: Some(seconds),
79 ..self.termination.unwrap_or_default()
80 });
81 self
82 }
83
84 pub fn with_random_seed(mut self, seed: u64) -> Self {
85 self.random_seed = Some(seed);
86 self
87 }
88
89 pub fn with_phase(mut self, phase: PhaseConfig) -> Self {
90 self.phases.push(phase);
91 self
92 }
93
94 pub fn time_limit(&self) -> Option<Duration> {
112 self.termination.as_ref().and_then(|t| t.time_limit())
113 }
114}
115
116#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize)]
118#[serde(rename_all = "snake_case")]
119pub enum EnvironmentMode {
120 #[default]
122 NonReproducible,
123
124 Reproducible,
126
127 FastAssert,
129
130 FullAssert,
132}
133
134#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
136#[serde(rename_all = "snake_case")]
137pub enum MoveThreadCount {
138 #[default]
140 Auto,
141
142 None,
144
145 Count(usize),
147}
148
149#[derive(Debug, Clone, Default)]
151pub struct SolverConfigOverride {
152 pub termination: Option<TerminationConfig>,
154}
155
156impl SolverConfigOverride {
157 pub fn with_termination(termination: TerminationConfig) -> Self {
158 SolverConfigOverride {
159 termination: Some(termination),
160 }
161 }
162}