cog_task/server/task/
config.rs1use crate::resource::{
2 AudioBackend, Color, Interpreter, LogFormat, StreamBackend, TimePrecision, UseTrigger, Volume,
3};
4use eyre::{eyre, Result};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Default, Clone, Deserialize, Serialize)]
8#[serde(deny_unknown_fields)]
9pub struct Config {
10 #[serde(default = "defaults::use_trigger")]
11 use_trigger: UseTrigger,
12 #[serde(default = "defaults::verify_sha2")]
13 #[serde(skip_serializing)]
14 verify_sha2: Option<String>,
15 #[serde(default = "defaults::blocks_per_row")]
16 blocks_per_row: i32,
17 #[serde(default = "defaults::volume")]
18 volume: Volume,
19 #[serde(default = "defaults::log_format")]
20 log_format: LogFormat,
21 #[serde(default = "defaults::time_precision")]
22 time_precision: TimePrecision,
23 #[serde(default = "defaults::interpreter")]
24 interpreter: Interpreter,
25 #[serde(default = "defaults::audio_backend")]
26 audio_backend: AudioBackend,
27 #[serde(default = "defaults::stream_backend")]
28 stream_backend: StreamBackend,
29 #[serde(default = "defaults::background")]
30 background: Color,
31}
32
33mod defaults {
34 use crate::resource::{
35 AudioBackend, Color, Interpreter, LogFormat, StreamBackend, TimePrecision, UseTrigger,
36 Volume,
37 };
38 use cfg_if::cfg_if;
39
40 #[inline(always)]
41 pub fn use_trigger() -> UseTrigger {
42 UseTrigger::Yes
43 }
44
45 #[inline(always)]
46 pub fn verify_sha2() -> Option<String> {
47 None
48 }
49
50 #[inline(always)]
51 pub fn blocks_per_row() -> i32 {
52 3
53 }
54
55 #[inline(always)]
56 pub fn volume() -> Volume {
57 Volume::Value(1.0)
58 }
59
60 #[inline(always)]
61 pub fn log_format() -> LogFormat {
62 LogFormat::RON
63 }
64
65 #[inline(always)]
66 pub fn time_precision() -> TimePrecision {
67 TimePrecision::RespectBoundaries
68 }
69
70 #[inline(always)]
71 pub fn interpreter() -> Interpreter {
72 Interpreter::Fasteval
73 }
74
75 #[inline(always)]
76 pub fn audio_backend() -> AudioBackend {
77 cfg_if! {
78 if #[cfg(feature = "rodio")] {
79 AudioBackend::Rodio
80 } else {
81 AudioBackend::None
82 }
83 }
84 }
85
86 #[inline(always)]
87 pub fn stream_backend() -> StreamBackend {
88 cfg_if! {
89 if #[cfg(feature = "gstreamer")] {
90 StreamBackend::Gst
91 } else if #[cfg(feature = "ffmpeg")] {
92 StreamBackend::Ffmpeg
93 } else {
94 StreamBackend::None
95 }
96 }
97 }
98
99 #[inline(always)]
100 pub fn background() -> Color {
101 Color::Transparent
102 }
103}
104
105impl Config {
106 pub fn init(&mut self) -> Result<()> {
107 self.volume = self.volume.or(&defaults::volume());
108 self.use_trigger = self.use_trigger.or(&defaults::use_trigger());
109 self.time_precision = self.time_precision.or(&defaults::time_precision());
110 self.log_format = self.log_format.or(&defaults::log_format());
111 self.interpreter = self.interpreter.or(&defaults::interpreter());
112 self.audio_backend = self.audio_backend.or(&defaults::audio_backend());
113 self.stream_backend = self.stream_backend.or(&defaults::stream_backend());
114 self.background = self.background.or(&defaults::background());
115 Ok(())
116 }
117
118 #[inline(always)]
119 pub fn volume(&self) -> Volume {
120 self.volume
121 }
122
123 #[inline(always)]
124 pub fn use_trigger(&self) -> UseTrigger {
125 self.use_trigger
126 }
127
128 pub fn verify_checksum(&self, task: String) -> Result<()> {
129 if let Some(checksum) = self.verify_sha2.as_ref() {
130 if checksum != &task {
131 return Err(eyre!(
132 "Checksum of this task does not match the one on file.\n\
133 Current: {task}\n\
134 On file: {checksum}"
135 ));
136 }
137 }
138 Ok(())
139 }
140
141 #[inline(always)]
142 pub fn blocks_per_row(&self) -> i32 {
143 self.blocks_per_row
144 }
145
146 #[inline(always)]
147 pub fn log_format(&self) -> LogFormat {
148 self.log_format
149 }
150
151 #[inline(always)]
152 pub fn time_precision(&self) -> TimePrecision {
153 self.time_precision
154 }
155
156 #[inline(always)]
157 pub fn interpreter(&self) -> Interpreter {
158 self.interpreter
159 }
160
161 #[inline(always)]
162 pub fn audio_backend(&self) -> AudioBackend {
163 self.audio_backend
164 }
165
166 #[inline(always)]
167 pub fn stream_backend(&self) -> StreamBackend {
168 self.stream_backend
169 }
170
171 #[inline(always)]
172 pub fn background(&self) -> Color {
173 self.background
174 }
175}
176
177#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize)]
178#[serde(deny_unknown_fields)]
179pub struct OptionalConfig {
180 #[serde(default)]
181 volume: Volume,
182 #[serde(default)]
183 use_trigger: UseTrigger,
184 #[serde(default)]
185 log_format: LogFormat,
186 #[serde(default)]
187 time_precision: TimePrecision,
188 #[serde(default)]
189 interpreter: Interpreter,
190 #[serde(default)]
191 audio_backend: AudioBackend,
192 #[serde(default)]
193 stream_backend: StreamBackend,
194 #[serde(default)]
195 background: Color,
196}
197
198impl OptionalConfig {
199 pub fn fill_blanks(&self, base_config: &Config) -> Config {
200 let mut config = base_config.clone();
201 config.volume = self.volume.or(&base_config.volume);
202 config.use_trigger = self.use_trigger.or(&base_config.use_trigger);
203 config.time_precision = self.time_precision.or(&config.time_precision);
204 config.log_format = self.log_format.or(&base_config.log_format);
205 config.interpreter = self.interpreter.or(&config.interpreter);
206 config.audio_backend = self.audio_backend.or(&config.audio_backend);
207 config.stream_backend = self.stream_backend.or(&config.stream_backend);
208 config.background = self.background.or(&config.background);
209 config
210 }
211}