hyperion/models/
global.rs

1use std::num::NonZeroUsize;
2
3use serde_derive::{Deserialize, Serialize};
4use validator::Validate;
5
6use super::ServerConfig;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
9#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
10pub struct FlatbuffersServer {
11    pub enable: bool,
12    #[validate(range(min = 1024))]
13    pub port: u16,
14    #[validate(range(min = 1))]
15    pub timeout: u32,
16}
17
18impl Default for FlatbuffersServer {
19    fn default() -> Self {
20        Self {
21            enable: true,
22            port: 19400,
23            timeout: 5,
24        }
25    }
26}
27
28impl ServerConfig for FlatbuffersServer {
29    fn port(&self) -> u16 {
30        self.port
31    }
32}
33
34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
35#[serde(default, deny_unknown_fields)]
36pub struct Forwarder {
37    pub enable: bool,
38    pub json: Vec<String>,
39    pub flat: Vec<String>,
40}
41
42impl Default for Forwarder {
43    fn default() -> Self {
44        Self {
45            enable: false,
46            json: vec!["127.0.0.1:19446".to_owned()],
47            flat: vec!["127.0.0.1:19401".to_owned()],
48        }
49    }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
53#[serde(rename_all = "lowercase", deny_unknown_fields)]
54#[derive(Default)]
55pub enum FramegrabberType {
56    #[default]
57    Auto,
58    AMLogic,
59    DispmanX,
60    DirectX9,
61    Framebuffer,
62    OSX,
63    QT,
64    X11,
65    XCB,
66}
67
68#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
69#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
70pub struct Framegrabber {
71    #[serde(rename = "type")]
72    pub ty: FramegrabberType,
73    #[validate(range(min = 10))]
74    pub width: u32,
75    #[validate(range(min = 10))]
76    pub height: u32,
77    #[serde(rename = "frequency_Hz")]
78    #[validate(range(min = 1))]
79    pub frequency_hz: u32,
80    pub crop_left: u32,
81    pub crop_right: u32,
82    pub crop_top: u32,
83    pub crop_bottom: u32,
84    #[validate(range(min = 1, max = 30))]
85    pub pixel_decimation: u32,
86    #[serde(default)]
87    pub display: u32,
88}
89
90impl Default for Framegrabber {
91    fn default() -> Self {
92        Self {
93            ty: Default::default(),
94            width: 80,
95            height: 45,
96            frequency_hz: 10,
97            crop_left: 0,
98            crop_right: 0,
99            crop_top: 0,
100            crop_bottom: 0,
101            pixel_decimation: 8,
102            display: 0,
103        }
104    }
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
108pub enum WatchedVersionBranch {
109    Stable,
110    Beta,
111    Alpha,
112}
113
114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
115#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
116pub struct General {
117    #[validate(length(min = 4, max = 20))]
118    pub name: String,
119    pub watched_version_branch: WatchedVersionBranch,
120    pub show_opt_help: bool,
121}
122
123impl Default for General {
124    fn default() -> Self {
125        Self {
126            name: "My Hyperion Config".to_owned(),
127            watched_version_branch: WatchedVersionBranch::Stable,
128            show_opt_help: true,
129        }
130    }
131}
132
133#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
134#[serde(rename_all = "SCREAMING_SNAKE_CASE", deny_unknown_fields)]
135#[derive(Default)]
136pub enum V4L2Standard {
137    #[default]
138    NoChange,
139    Pal,
140    Ntsc,
141    Secam,
142}
143
144#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
145#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
146pub struct GrabberV4L2 {
147    pub device: String,
148    pub input: i32,
149    pub standard: V4L2Standard,
150    pub width: u32,
151    pub height: u32,
152    #[validate(range(min = 1))]
153    pub fps: u32,
154    #[validate(range(min = 1, max = 30))]
155    pub size_decimation: u32,
156    pub crop_left: u32,
157    pub crop_right: u32,
158    pub crop_top: u32,
159    pub crop_bottom: u32,
160    pub cec_detection: bool,
161    pub signal_detection: bool,
162    #[validate(range(min = 0, max = 100))]
163    pub red_signal_threshold: u32,
164    #[validate(range(min = 0, max = 100))]
165    pub green_signal_threshold: u32,
166    #[validate(range(min = 0, max = 100))]
167    pub blue_signal_threshold: u32,
168    #[serde(rename = "sDVOffsetMin")]
169    #[validate(range(min = 0., max = 1.))]
170    pub sdv_offset_min: f32,
171    #[serde(rename = "sDVOffsetMax")]
172    #[validate(range(min = 0., max = 1.))]
173    pub sdv_offset_max: f32,
174    #[serde(rename = "sDHOffsetMin")]
175    #[validate(range(min = 0., max = 1.))]
176    pub sdh_offset_min: f32,
177    #[serde(rename = "sDHOffsetMax")]
178    #[validate(range(min = 0., max = 1.))]
179    pub sdh_offset_max: f32,
180}
181
182impl Default for GrabberV4L2 {
183    fn default() -> Self {
184        Self {
185            device: "auto".to_owned(),
186            input: 0,
187            standard: Default::default(),
188            width: 0,
189            height: 0,
190            fps: 15,
191            size_decimation: 6,
192            crop_left: 0,
193            crop_right: 0,
194            crop_top: 0,
195            crop_bottom: 0,
196            cec_detection: false,
197            signal_detection: false,
198            red_signal_threshold: 5,
199            green_signal_threshold: 5,
200            blue_signal_threshold: 5,
201            sdv_offset_min: 0.25,
202            sdv_offset_max: 0.75,
203            sdh_offset_min: 0.25,
204            sdh_offset_max: 0.75,
205        }
206    }
207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Validate)]
210#[serde(default, deny_unknown_fields)]
211pub struct JsonServer {
212    #[validate(range(min = 1024))]
213    pub port: u16,
214}
215
216impl Default for JsonServer {
217    fn default() -> Self {
218        Self { port: 19444 }
219    }
220}
221
222impl ServerConfig for JsonServer {
223    fn port(&self) -> u16 {
224        self.port
225    }
226}
227
228#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
229#[serde(rename_all = "lowercase", deny_unknown_fields)]
230pub enum LoggerLevel {
231    Silent,
232    Warn,
233    Verbose,
234    Debug,
235}
236
237#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
238#[serde(default, deny_unknown_fields)]
239pub struct Logger {
240    pub level: LoggerLevel,
241}
242
243impl Default for Logger {
244    fn default() -> Self {
245        Self {
246            level: LoggerLevel::Warn,
247        }
248    }
249}
250
251#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
252#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
253pub struct Network {
254    pub api_auth: bool,
255    #[serde(default, rename = "internetAccessAPI")]
256    pub internet_access_api: bool,
257    #[serde(
258        default,
259        rename = "restrictedInternetAccessAPI",
260        alias = "restirctedInternetAccessAPI"
261    )]
262    pub restricted_internet_access_api: bool,
263    pub ip_whitelist: Vec<String>,
264    pub local_api_auth: bool,
265    pub local_admin_auth: bool,
266}
267
268impl Default for Network {
269    fn default() -> Self {
270        Self {
271            api_auth: true,
272            internet_access_api: false,
273            restricted_internet_access_api: false,
274            ip_whitelist: vec![],
275            local_api_auth: false,
276            local_admin_auth: true,
277        }
278    }
279}
280
281#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
282#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
283pub struct ProtoServer {
284    pub enable: bool,
285    #[validate(range(min = 1024))]
286    pub port: u16,
287    #[validate(range(min = 1))]
288    pub timeout: u32,
289}
290
291impl Default for ProtoServer {
292    fn default() -> Self {
293        Self {
294            enable: true,
295            port: 19445,
296            timeout: 5,
297        }
298    }
299}
300
301impl ServerConfig for ProtoServer {
302    fn port(&self) -> u16 {
303        self.port
304    }
305}
306
307#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
308#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
309pub struct WebConfig {
310    #[serde(rename = "document_root")]
311    pub document_root: String,
312    #[validate(range(min = 80))]
313    pub port: u16,
314    #[validate(range(min = 80))]
315    pub ssl_port: u16,
316    pub crt_path: String,
317    pub key_path: String,
318    pub key_pass_phrase: String,
319    pub max_sessions: NonZeroUsize,
320}
321
322impl WebConfig {
323    pub const SYSTEM_DOCUMENT_ROOT: &'static str = "$ROOT/webconfig";
324}
325
326impl Default for WebConfig {
327    fn default() -> Self {
328        Self {
329            document_root: String::new(),
330            port: 8090,
331            ssl_port: 8092,
332            crt_path: String::new(),
333            key_path: String::new(),
334            key_pass_phrase: String::new(),
335            max_sessions: NonZeroUsize::new(4).unwrap(),
336        }
337    }
338}
339
340#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
341#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
342pub struct Hooks {
343    /// Command to run when an instance is started. HYPERION_INSTANCE_ID environment variable
344    /// will hold the instance id.
345    pub instance_start: Vec<String>,
346    /// Command to run when an instance is stopped. HYPERION_INSTANCE_ID environment variable
347    /// will hold the instance id.
348    pub instance_stop: Vec<String>,
349    /// Command to run when an instance is activated. HYPERION_INSTANCE_ID environment variable
350    /// will hold the instance id.
351    pub instance_activate: Vec<String>,
352    /// Command to run when an instance is deactivated. HYPERION_INSTANCE_ID environment variable
353    /// will hold the instance id.
354    pub instance_deactivate: Vec<String>,
355    /// Command to run when hyperion.rs starts
356    pub start: Vec<String>,
357    /// Command to run when hyperion.rs stops
358    pub stop: Vec<String>,
359}
360
361#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Validate)]
362#[serde(default, rename_all = "camelCase", deny_unknown_fields)]
363pub struct GlobalConfig {
364    pub flatbuffers_server: FlatbuffersServer,
365    pub forwarder: Forwarder,
366    pub framegrabber: Framegrabber,
367    pub general: General,
368    #[serde(rename = "grabberV4L2")]
369    pub grabber_v4l2: GrabberV4L2,
370    pub json_server: JsonServer,
371    pub logger: Logger,
372    pub network: Network,
373    pub proto_server: ProtoServer,
374    pub web_config: WebConfig,
375    pub hooks: Hooks,
376}